locked
SqlDependency and FIPS RRS feed

  • Question

  • Hello!

     

    I am developing with .NET 2.0 and SQL Sever 2005 on WinXP for a production system of Windows 2003 Server with FIPS enabled (http://www.itl.nist.gov/fipspubs/).

     

    When our team tries to use SqlDependency, we get FIPS exceptions.  I assume that this is because the inner workings use encryption algorithms that are not FIPS-compliant.  Is there a way to configure my application (or even the entire machine) such that SqlDependency will use FIPS-approved encryption?

     

    I guess my real question is how can I use SqlDependency on a FIPS-enabled machine?

     

    We have been using SqlNotificationRequest, but I'm now developing a client, of which, we require multiple instances.  So we've run into the problem where when multiple clients run, only one will receive and process a notification.

     

    Thanks!

    John

    Thursday, August 30, 2007 11:01 PM

Answers

  • Good question. SqlDependency has exactly the same problem and if you sneak with Profiler at what it does, you can that it uses a simple trick: it beguns a dialog on from the temporary service to itself w/o sending any message (for a change you could begin the dialog specifying 'with encryption = off' to avoid those ERRORLOG nastygrams Wink ).Then it begins a dialog timer on this dialog. This timer will fire after a specified timeout and will enqueue a timer message into the temprary queue. If there is no posted WAITFOR (RECEIVE.. ) on this queue, this message will activate the procedure attached with the queue. So if this procedure was ever activated, it means there was no posted WAITFOR(RECEIVE) on the queue, and this can be considered as a sign that the original connection was disconencted abrutly, so the service/queue/activated procedure can all be cleaned up. If the timer message is picked up by the client listenning thread, this thread has to post a new timer (issue BEGIN CONVERSATION TIMER again). Since dialog timers are persisted and transacted, this will ensure a cleanup even if, say, the database crashes and is restored on a new server...
    The only problem with this approach is taht it requires a many permissions (create queue, create service, create procedure). One can use a provissioning stored procedure (perhaps code signed) that is granted the necessary rights to create the temporary queue/service/procedure.
    Friday, September 7, 2007 8:16 PM

All replies

  • What do you mean by "FIPS exceptions". Please post the exact error and source of the error.

     

    Thanks,

    -mike

    Friday, August 31, 2007 4:13 AM
  • Here is a link which will better explain FIPS: http://technet2.microsoft.com/windowsserver/en/library/6ff574cb-30c4-4ad9-8d5e-aee697c65b9b1033.mspx?mfr=true

     

    Here is Microsoft's article explaining which technologies are FIPS-compliant: http://www.microsoft.com/technet/archive/security/topics/issues/fipseval.mspx?mfr=true

     

    From the article:

    Code Snippet
    .NET Framework using the DESCryptoServiceProvider, TripleDESCryptoServiceProvider, SHA1CryptoServiceProvider, RSACryptoServiceProvider, DSACryptoServiceProvider, and RNGCryptoServiceProvider classes as they simple redirect of the caller requests to the Windows Platform FIPS-140 validated crypto modules

     

     

    When I look at the stack trace of the exception, I see that when SqlDependency is returning data, it creates an instance of System.Security.Cryptography.SHA1Managed using its explicit constructor.  The error that I get is as follows:

     

    Code Snippet
    Unhandled Exception: System.InvalidOperationException: This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms.

     

     

    Now, if Microsoft had used either of the following:
    • System.Security.Cryptography.SHA1.Create
    • System.Security.Cryptography.CryptoConfig.CreateFromName("System.Security.Cryptography.SHA1")
    • System.Security.Cryptography.HashAlgorithm.Create

    I could have configured the machine.config file like this so that the SqlDependency class would have used the FIPS-approved System.Security.Cryptography.SHA1CryptoServiceProvider.

     

    Is there any way that this could be reviewed in any future .NET Framework service packs?  As it stands now, your extremely useful SqlDependency class (and likely others) is entirely unusble by any system that has FIPS requirements, which is a large swath of government systems, health-care systems, and - for some strange reason - information systems in California (lol?).

     

    Any thoughts?

    ~ jR

     

    Friday, August 31, 2007 3:47 PM
  • Just a side note, Service Broker uses FIPS 140-2 compliant algorithms when running on a FIPS compliant box (the ERRORLOG will print a message that Service Broker is running in FIPS compliance mode), but a service hosted on a SQL instance runing on a FIPS compliant box will have to use dialogs w/o security  (ENCRYPTION = OFF, no REMOTE SERVICE BINDING) to talk with a service hosted on a non-compliant box (because the compliant box will use AES for dialog encryption and the normal non-compliant will use RC4 and ther eis no configuration knob to control this). Traffic can still be encrypted between the two boxes can still be encrypted at the endpoint level, since both endpoints can be configured to use AES encryption. and to complete the picture, the message signing is SHA-1.
    When the traffic is all within one SQL Server instance (like normally SqlDependency is), then FIPS compliance should not matter.
    Friday, August 31, 2007 3:49 PM
  • This is a client issue (.Net code) not a Service Broker issue (SQL Server). I don't know what the SqlDependency does to trigger this, but I'm surprised that the .Net crypto framework throws exception for usage of SHA-1, since AFAIK SHA-1 is a compliant algorithm ('blessed by 180-2 and not yet supersseeded). While is tru that recent research devlopments are making future use of SHA-1 risky, today is still approved by FIPS and the NT Crypto providers allow it's usage when the the FIPS compliance mode is turned on.
    Friday, August 31, 2007 4:12 PM
  • Remus,

     

    First of all, thank you for your blog: I read through all of it yesterday and learned a lot.

     

    Be careful when you say that SHA1 is "blessed" by FIPS because - in the context of the .NET Framework - there are 2 distinct types of SHA1: Managed and the wrapped cryptographic service provider (CSP).  The wrapped CSP (System.Security.Cryptography.SHA1CryptoServiceProvider) is FIPS-compliant.  The Managed one (System.Security.Cryptography.SHA1Managed) is not.

     

    SqlDependency uses System.Security.Cryptography.SHA1Managed explicitly (using its constructor) instead of using CryptoConfig, which would allow me to specify which SHA1 to use.

     

    Does that help?

    John Ruiz

     

    Friday, August 31, 2007 4:21 PM
  • I didn't know that, but it figures. AFAIK The only cryptographic package from MS that are FIPS compliant certified are the NT CSP (the Base and the Enhanced providers), and the SHA1CryptoServiceProvider is probably a wrapper around the NT API. SHA1Managed must be the .Net own implementation, and thus not compliant.
    Friday, August 31, 2007 5:08 PM
  • I've split your post into the SQL Server Data Access forum at http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=87&SiteID=1
    Friday, August 31, 2007 5:16 PM
  • I moved the split from SQL Server Data Access to .NET data access and storage at http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2079623&SiteID=1

     

    There should be plenty of experts on .NET there to help you resolve your situation.

     

    Friday, August 31, 2007 5:56 PM
  •  

    As it turns out, I didn't get a single response.  Thanks for trying, though.
    Thursday, September 6, 2007 9:13 PM
  • Anyway, you can always use the basic SqlNotificationRequest. You get higher flexibility and maybe even that ever elusive goal, correctness...
    Friday, September 7, 2007 5:47 AM
  • Remus,

     

    That's exactly what we're going to do: we're going to use SqlNotificationRequest and create queues and their services on the fly each time the GUI starts, and delete them when it closes.  We'll append a GUID to the queue and service name to allow multiple concurrent instances of the GUI.

     

    Here's our concern, though...

     

    What happens when the GUI crashes and the code to DROP the queue and service doesn't execute?  How do you recommend that we periodically check for and remove orphaned queues and services?

     

    Thanks!

    ~ jR

     

     

    Friday, September 7, 2007 7:49 PM
  • Good question. SqlDependency has exactly the same problem and if you sneak with Profiler at what it does, you can that it uses a simple trick: it beguns a dialog on from the temporary service to itself w/o sending any message (for a change you could begin the dialog specifying 'with encryption = off' to avoid those ERRORLOG nastygrams Wink ).Then it begins a dialog timer on this dialog. This timer will fire after a specified timeout and will enqueue a timer message into the temprary queue. If there is no posted WAITFOR (RECEIVE.. ) on this queue, this message will activate the procedure attached with the queue. So if this procedure was ever activated, it means there was no posted WAITFOR(RECEIVE) on the queue, and this can be considered as a sign that the original connection was disconencted abrutly, so the service/queue/activated procedure can all be cleaned up. If the timer message is picked up by the client listenning thread, this thread has to post a new timer (issue BEGIN CONVERSATION TIMER again). Since dialog timers are persisted and transacted, this will ensure a cleanup even if, say, the database crashes and is restored on a new server...
    The only problem with this approach is taht it requires a many permissions (create queue, create service, create procedure). One can use a provissioning stored procedure (perhaps code signed) that is granted the necessary rights to create the temporary queue/service/procedure.
    Friday, September 7, 2007 8:16 PM
  • Remus,

     

    That's a pretty good trick.  I have one concern about it, however, and I'd like to see what you think.

    1. BEGIN DIALOG w/TIMEOUT
    2. The client posts a WAITFOR(RECEIVE..), waiting for a message.
    3. Something happens which causes a message to go on the queue
    4. The client's WAITFOR(RECEIVE..) returns
    5. The client begins executing code to post another WAITFOR(RECEIVE..)
    6. Just at the perfect moment, BEGIN DIALOG w/TIMEOUT times out and a message is enqueued
    7. The client hasn't yet posted another WAITFOR(RECEIVE..)
    8. The queue activates the stored procedure, which cleans everything up.
    9. The client tries to post a WAITFOR(RECEIVE..) and everything melts.  The universe divides by zero.

    Thoughts?

    John

     

    Tuesday, October 2, 2007 2:56 PM
  • Hehe, good catch. Well, some says the singularity is not that bad after all...
    The activated procedure can actually check the management views (sys.dm_exec_connections, sys.dm_exec_sessions) to validate if the app thread is still around or not. The activated procedure will have to pass the security hurdles described here: http://blogs.msdn.com/remusrusanu/archive/2006/03/01/541882.aspx to access these views though.
    Tuesday, October 2, 2007 3:43 PM