We haven’t seen it a lot, but more often lately and interesting enough a problem that I thought I’d write a blog article on this issue.
In this blog article, we’ll define what the Windows Platform FIPS Encryption Policy is and then how we can make SmartConnect work with this policy enabled.
So, the easy question to start with is: What is the Windows Platform FIPS Encryption Policy?
According to Microsoft, “FIPS” is the standard that defines security and interoperability requirements for computer systems that are used by the U.S. federal government.
The whole article is very dry but suffice to say it has various specifications for encryption algorithms and TLS on the connections made by the application.
How do I enabled/disable this setting?
There are a lot of articles out there that discuss how to do so, this StackOverFlow question & answer gives the best way using the Local Policy Editor.
How will I know that SmartConnect is no longer working correctly after enabling FIPS?
That’s easy – it’ll throw an unhandled .NET exception on launch.
Figure 1:SmartConnect fails on launch
The full error message is:
System.InvalidOperationException: This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms.
at eOne.SmartConnect.Engine.EncryptionHelper.DecryptStringAES(String cipherText)
at eOne.SmartConnect.Engine.AppConfigHelper.GetEncryptedValueForSection(Boolean production, String key)
at eOne.SmartConnect.UI.External.FormLogin.FormLogin_Load(Object sender, EventArgs e)
at System.EventHandler.Invoke(Object sender, EventArgs e)
<previous lines removed>
OK, we know what FIPS is and see that it breaks SmartConnect, how do we fix it?
The resolution is a built-in .NET feature that Microsoft added to disable FIPS in a .NET application on an application by application basis. This Microsoft Blog article talks about the resolution.
In a nutshell, we just need to create the various eOne.SmartConnect.XXX.exe.config files and add in just those lines to it. Because .NET automatically looks for a “config” file for every executable, that means that we need four config files (that look the same) for each of the four executables in the SmartConnect folder.
Figure 2: Two of the four configuration files highlighted with contents
The files include any executable in the SmartConnect folder which currently are (as of 184.108.40.206):
OK, I did all of that and SmartConnect works again. But I just found out that my SmartConnect Web Services don’t seem to work anymore. Is this related?
Yes, it is because it is the same underlying issue. The SmartConnect code run by IIS still must decrypt the configuration information and credentials using the same methods that the UI executable does and therefore we would expect it to get the same underlying error.
We can see that if we try to browse the legacy SmartConnect asmx service, it fails.
Figure 3:SmartConnect web service fails after enable FIPS
The error doesn’t appear to be the same issue as the SmartConnect desktop client and implies that we just need to adjust the configuration settings – nothing related to the FIPS settings.
However, since the desktop client fails without adding the configuration changes, we might guess that the web service would fail as well. If we were interested (I was) and wanted to verify this, I used Windbg to view the actual exceptions and display them.
Figure 4: errors on w3wp.exe using Windb
If we look at the Managed Exceptions on the w3wp.exe (which is the IIS worker process), we can see the real exception is the same which is caught by SmartConnect this time (since IIS doesn’t crash) and then handled by throwing the “nice” message that we see in the browser.
That’s all very interesting, but how do we fix this in IIS for my SmartConnect Web Services and SmartConnect Web Client?
This can be solved in couple different ways. It would be convenient if we could modify the web.config for each of these Web Sites – but unfortunately the settings that work in the exe.config files don’t apply to the Web Config. But as I noted, we can still make this work.
The easiest way to make this work is to break out The Big Hammer.
According to this StackOverFlow article, one of the comments suggest that we modify the Aspnet.config file which is located in your Framework v4 folder (since SmartConnect is 32bit and using .NET 4.5/4.71 depending on version of SC).
The default location for this file is:
Figure 5: configuration setting applied to Aspnet.config file
The above is my modified version of that Aspnet.config file and the only thing I changed is added the highlighted enforceFIPSPolicy line as noted.
If I restart my Web Service application pool(s), then once again SmartConnect Web Services & the SmartConnect Web Client started working again.
I’m tempted to just leave it at “modify the Aspnet.config file” but I’m not a fan of The Big Hammer approach because any .NET 4.x install using 32bit application (like SmartConnect) would then have the FIPS policy disabled. I suspect that for 99.9% of our users, this is going to be fine.
But for that .1% where “No, we can’t enable it for just anything on the web server, it can only be disabled for SmartConnect web stuff” then there is a way to do it per application pool in IIS.
According to this article, there is the ability in IIS 7.5 that adds a CRLConfigFile property to the application pool configuration.
By adding this property, we can essentially have the “exe.config” that we wished we could do in the Web.Config but cannot.
I created a text file I called noFIPSWeb.config with the new policy setting and copied it into my SmartConnect www folder.
Because my IIS user is a local administrator, I can ignore the permissions piece referenced in that article.
Figure 6: Bypassing the FIPS Policy on the application pool
From an Admin command prompt, I ran:
%windir%\System32\inetsrv\appcmd.exe set config -section:system.applicationHost/applicationPools /[name=’SmartConnect‘].CLRConfigFile:”c:\Program Files (x86)\eOne Solutions\www\noFipsWeb.config” /commit:apphost
In the screenshot, we can see that the appcmd.exe results are “Applied configuration changes …” meaning it was successful.
And if I try to browse that same URL as before, it is now successful.
If I had the SmartConnectWcf Web Service or the SmartConnect Web Client loaded, I would copy that same noFIPS.config file into their respective folders and then run the same command line as above changing the path of “www” to “wcf” and “SmartConnectWebClient” and then the name=’SmartConnect’ to name=’SmartConnectWcf’ and name=’SmartConnectWebClient’ respectively.
This would then enable the same CLRConfigFile and allow these applications to also work again.
The configuration files referenced in this blog article can be found HERE.
To use these files:
1 For the eOne.SmartConnect.*.exe.config files, you can copy them into the SmartConnect folder as-is and SmartConnect will now work with FIPS
2. For the Aspnet.config file, you likely can drop that in the folder as well – however since I don’t know if your default is the same as my default, you are safest to just add the line as I did.
If you do this and use the Aspnet.config file, then you DO NOT need to do number 3 and 4 below.
3. The NoFipsWeb.config can be dropped into the \www, \wcf, and \SmartConnectWeb folders as-is.
4. appcmd for IIS.txt – This file contains the 3 commands to run at an elevated/admin command prompt and is configured for the default names and file paths for SmartConnect Web Components.