| Join | Help

August 2007 - Posts

.NET 2.0 and FIPS

Starting in the .NET Framework 2.0, some of the Cryptographic Classes no longer work if FIPS compliance is forced on the Server.

Currently, none of the Managed hashing classes will work on a FIPS enabled server. Attempting to use those results in the exception:

"InvalidOperationException: This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms."

This can be problematic for high security environments. The only hashing algorithm that does work in a FIPS environment is the SHA1CryptoServiceProvider. This class uses unmanaged calls to the CSP in Windows.

Your use of symmetric algorithms is greatly decreased. The Rijndael algorithms will not work, however the TripleDESCryptoServiceProvider.

You should start to see a pattern: None of the managed implementations of an algorithm are marked as FIPS Compliant. However, all of the Service Providers (ones that use the CSP) will not cause this exception.

Share this post: | bookmark it! | digg it! | reddit! | kick it! | live it!
Posted by Kevin Jones with no comments
Filed under:
Tuesday, August 07, 2007 6:58 PM

The Folly of FindOne in 1.1.

Recently while working, myself and an co-worker discovered that there is a memory leak in the FindOne method of the DirectorySearcher class in System.DirectoryServices. The leak occurs when FindOne returns null. This is only fixed in the 2.0 Framework, and currently that isn't an option for us. However, I wrote a DirectorySearcher called SafeDirectorySearcher that eliminates this problem. It contains a method called "FindOneSafe" which should be used in place of FindOne. It uses a bit of reflection to access a private method:

public class SafeDirectorySearcher : DirectorySearcher
{
 public SearchResult FindOneSafe()
 {
  MethodInfo methodInfo = typeof(DirectorySearcher).GetMethod("FindAll", BindingFlags.Instance | BindingFlags.NonPublic, null, CallingConventions.Any, new Type[] {typeof(bool)}, null);
  SearchResultCollection results = (SearchResultCollection) methodInfo.Invoke(this, new object[] { false });
  try
  {
   foreach (SearchResult result in results)
   {
    return result;
   }
   return null;
  }
  finally
  {
   results.Dispose();
  }
 }

 public SafeDirectorySearcher(DirectoryEntry searchRoot) : base(searchRoot)
 {
 }
 
 public SafeDirectorySearcher(string searchRoot) : base(searchRoot)
 {
 }

 public SafeDirectorySearcher() : base()
 {
 }

 public SafeDirectorySearcher(string filter, string[] propertiesToLoad) : base(filter, propertiesToLoad)
 {
 }

 public SafeDirectorySearcher(DirectoryEntry searchRoot, string filter, string[] propertiesToLoad) : base(searchRoot, filter, propertiesToLoad)
 {
 }

 public SafeDirectorySearcher(string filter, string[] propertiesToLoad, SearchScope scope) : base(filter, propertiesToLoad, scope)
 {
 }

 public SafeDirectorySearcher(DirectoryEntry searchRoot, string filter, string[] propertiesToLoad, SearchScope scope) : base (searchRoot, filter, propertiesToLoad, scope)
 {
 }

 [Obsolete("This method is known to have a memory leak. Use with caution!", false)]
 public new SearchResult FindOne()
 {
  return base.FindOne();
 }
}

Share this post: | bookmark it! | digg it! | reddit! | kick it! | live it!
Posted by Kevin Jones with no comments
Filed under: