Sunday, November 25, 2012

Transferring Data Securely - Part 2 - Symmetric Cryptography

This is the second post of a multi-part post in which I will cover how to sign a message, encrypt it using Symmetric cryptography (with a random key), and then Asymmetrically encrypt the random key.  In my previous post, I covered how to obtain a digital signature for a set of data.  In this post, I will show you how to symmetrically encrypt the data using a randomly generated key and initialization vector (IV).

To make things easier, I like to use a Symmetric utility with state, but this is just personal preference.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace BlogSandbox.encryption
{
    public class SymmetricEncryption
    {
        public SymmetricAlgorithm Provider { get; set; }

        public SymmetricEncryption
            (SymmetricAlgorithm provider, 
            int keySize)
        {
            Provider = provider;
            provider.KeySize = keySize;
        }

        public SymmetricEncryption(
            SymmetricAlgorithm provider, 
            byte[] key, 
            byte[] iv)
        {
            Provider = provider;
            provider.Key = key;
            provider.IV = iv;
        }

        public byte[] GetKey() 
        { 
            return Provider.Key;    
        }

        public byte[] GetIv() 
        {
            return Provider.IV;
        }

        public byte[] Encrypt(byte[] message)
        {
            return TransformMessage(message, 
                Provider.CreateEncryptor());
        }

        public string Encrypt(string message)
        {
            byte[] encrypted = TransformMessage(
                        Encoding.UTF8.GetBytes(message), 
                        Provider.CreateEncryptor());
            return Convert.ToBase64String(encrypted);
        }

        public byte[] Decrypt(byte[] message)
        {
            return TransformMessage(message,
                Provider.CreateDecryptor());
        }

        public string Decrypt(string message)
        {
            byte[] decrypted = TransformMessage(
                        Convert.FromBase64String(message),
                        Provider.CreateDecryptor());
            return Encoding.UTF8.GetString(decrypted);
        }

        private byte[] TransformMessage(byte[] message, 
                        ICryptoTransform cryptoTransform)
        {
            MemoryStream memoryStream = new MemoryStream();
            CryptoStream cryptoStream = new CryptoStream(
                                    memoryStream, 
                                    cryptoTransform, 
                                    CryptoStreamMode.Write);

            // write message to be encrypted and flush
            cryptoStream.Write(message, 0, message.Length);
            cryptoStream.FlushFinalBlock();

            // read encrypted message into a byte[]
            memoryStream.Position = 0;
            byte[] result = memoryStream.ToArray();

            // close up the streams
            memoryStream.Close();
            cryptoStream.Close();

            return result;
        }
    }
}
The majority of work being done here is in the TransformMessage method.  By taking in the ICryptoTransform, we can handle both the encryption and the decryption using the same method.  The CryptoStream does all the work for us by converting the message using the encryptor or decryptor and placing the data in the MemoryStream.  I have included the "String" methods here because it is a bit tricky to get the encoding/decoding right.  Notice that when you get a string to be encrypted, you must convert it using the Encoding.UTF8.GetBytes method, but when returning the encrypted string you return it using the Convert.ToBase64String method.  This is very important, if you convert it in UTF8, you will lose data and not be able to decrypt it again.  When performing the decrypt, you do the opposite, get the bytes using the Convert.FromBase64String and convert the bytes using the Encoding.UTF8.GetString method.

When using this utility, you have the option of passing in your own key/IV or having it randomly generated by the provider.  In the test code, I will simply have it generated by the provider and is the use case for all of these posts. Here is some test code:

namespace BlogSandbox
{
    class Program
    {
        static void Main(string[] args)
        {
            string testText = "encrypt and decrypt me";

            SymmetricEncryption enc = new SymmetricEncryption(
                CryptoConfig.CreateFromName("AesManaged")
                    as SymmetricAlgorithm,
                256);

            string encText = enc.Encrypt(testText);
            Console.WriteLine("Encrypted: " + encText);
            string decText = enc.Decrypt(encText);
            Console.WriteLine("Decrypted: " + decText);
            Thread.Sleep(20000);
        }
    }
}
Notice how I obtained the provider "CryptoConfig.CreateFromName" - this takes advantage of Cryptographic Agility.  With cryptographic agility, you can assign different algorithms to a name (like "SymmAlgorithm") so that you can switch them for all programs using your library (configured per server).  While a very important topic, I won't be discussing this here... however, I strongly encourage you to google it and learn about it.

That's it for symmetric encryption/decryption.  In the next post I will cover Asymmetric encryption/decryption...

Saturday, October 27, 2012

Transferring Data Securely - Part 1 - Digital Signatures

It has been a while since my last post... in part b/c I have been so busy and in part b/c I really didn't have a good topic.  Recently I had to build an encryption library for work and I decided that there weren't any good posts showing how to securely transfer data using cryptography in .Net - so, I have decided to write a multi-part post that will cover how to sign a message, encrypt it using Symmetric cryptography (with a random key), and then Asymmetrically encrypt the random key.  I am not going to get into a whole lot of theoretical detail about Asymmetric cryptography, digital signatures, or Symmetric cryptography and why this is important - there are many great sources out there for this.  One thing I want to point out up front... I am not handling exceptions the way I would for a robust library.  I have not included exception handling so that I could focus on the code you need to understand - I have, however, tried to add comments in places where you might consider adding exception handling code.  Remember for all of the code snippets below to adjust the namespaces accordingly to match your workspace.

Ok, let's get started... step 1 will be to create a test certificate that you can use for testing all of this out.  Open the "Developer Command Prompt" which is located in the Visual Studios program folder.  If you can't find that, google makecert.exe and pvk2pfx.exe to find out where they are located and then copy them to a location where you can save certificates.  Once you have the command prompt open and have access to makecert and pvk2pfx, issue the following commands.  You can adjust the dates as desired, but keep the names (or adjust the name in the test code we will write below).

makecert.exe -sv TestCertificate.pvk -n "CN=TestCertificate" 
     TestCertificate.cer -sky Exchange -pe 
     -b 10/27/2012 -e 10/27/2020 -r

pvk2pfx.exe -pvk TestCertificate.pvk -spc TestCertificate.cer 
     -pfx TestCertificate.pfx
After executing the makecert command, a window will pop up asking for a password... you can chose to use one or just select none.  If you do select a password, remember it... you will need it to install the cert.  After executing these commands, you should have 3 files: TestCertificate.pfx, TestCertificate.pvk, and TestCertificate.cer.  Double click on TestCertificate.pfx and follow the instructions to install it.  If you added a password when running makecert, enter it when it tells you to.  You can keep all the default options, but I tend to select the option to "make the key exportable" - that is up to you.  Once your certificate is installed, it is time to add some code.

Next up, let's add a utility that we will use for other cryptographic work... I have created a folder named "encryption" where my classes will go... it is up to you how you want to organize your code.  Add a new class file called CryptoUtilities.cs and add the following code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

namespace BlogSandbox.encryption
{
    public class CryptoUtilities
    {
        // make sure certName passed in starts with 'CN='
        public static X509Certificate2 GetCertFromStore(
                                    StoreName storeName, 
                                    string certName)
        {
            X509Store store = new X509Store(storeName);
            store.Open(OpenFlags.ReadOnly);

            X509Certificate2Collection currentValidCerts =
                store.Certificates.Find(
                    X509FindType.FindByTimeValid, 
                    DateTime.Now, 
                    false);

            X509Certificate2Collection certs = 
                currentValidCerts.Find(
                    X509FindType.FindBySubjectDistinguishedName, 
                    certName, 
                    false);

            // check certs count and throw error if 0 if desired
            return certs[0];
        }
    }
}
Adjust the namespace as needed.  I have a couple recommendations here.  In this code, I am first finding all the valid certs that have not expired and then I am finding the certificate with "certName".  Since I am using "FindBySubjectDistinguishedName", the certName must start with "CN=".  I recommend that you add some code to check certName to see if it starts with CN= and if not, add it.  Also, I recommend that you check certs to make sure it has one (if you don't you will get an IndexOutOfRangeException - I think it is cleaner to instead throw a CryptographicException with a message indicating the cert could not be found, but it is up to you).  Ok, now that we have the ability to find the certificate, let's write the digital signature code.

Create a new class called DigitilSignature.cs and add the following code to it:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

namespace BlogSandbox.encryption
{
    class DigitalSignature
    {
        private const string DefaultAlgName = "sha1";

        public static byte[] SignMessage(
                                StoreName storeName,
                                string certName,
                                string algName,
                                byte[] message)
        {
            X509Certificate2 x509Cert = 
                CryptoUtilities.GetCertFromStore(
                                            storeName, 
                                            certName);
            RSACryptoServiceProvider digSigProvider = 
                x509Cert.PrivateKey as RSACryptoServiceProvider;

            // if no provider and no private key 
            // check for and throw exception
            return digSigProvider.SignData(
                message, 
                CryptoConfig.MapNameToOID(algName));
        }


        public static byte[] SignMessage(
                                StoreName storeName,
                                string certName,
                                byte[] message)
        {
            return SignMessage(storeName,
                               certName,
                               DefaultAlgName,
                               message);
        }

        public static bool VerifySignature(
                        StoreName storeName,
                        string certName,
                        string algName,
                        byte[] message,
                        byte[] signature)
        {
            X509Certificate2 x509Cert =
                CryptoUtilities.GetCertFromStore(
                                            storeName,
                                            certName);
            RSACryptoServiceProvider digSigProvider =
                x509Cert.PrivateKey as RSACryptoServiceProvider;

            // if no provider and no private key 
            // check for and throw exception
            return digSigProvider.VerifyData(
                message,
                CryptoConfig.MapNameToOID(algName),
                signature);
        }

        public static bool VerifySignature(
                        StoreName storeName,
                        string certName,
                        byte[] message,
                        byte[] signature)
        {
            return VerifySignature(storeName,
                               certName,
                               DefaultAlgName,
                               message,
                               signature);
        }
    }
}
Let's walk through these methods starting with SignMessage.  The first thing you will notice is that I there are 2 methods, one that takes in "algName" and one that does not (but instead uses a default "sha1").  This is to provide support for Cryptographic Agility... I will be adding another post to go over this in the future.  For now, let's just use "sha1".  As an aside, the certificate we created will only support "sha1" and I need a whole post just to go over creating a cert that you can use for sha2 algorithms.  Another thing you will probably notice is that there is some shared code in the sign/verify methods, feel free to abstract at will.  One thing I would like to mention is the method call CryptoConfig.MapNameToOID(algName) - this is for Cryptographic Agility and it internally maps the algorithm name "sha1" to an object identifier that the system understands as a SHA1 algorithm.  In a future post, I will try to expand on this some more and show you how you can map different names and make it possible to use very generic names (like "HashAlgorithm") that you can map to your preferred algorithms (particularly important for government work where you must use SHA2 based algorithms).  The only real difference between the sign and verify methods is that the sign method takes a message and an algorithm and then returns the signature as a byte[] while the verify takes the message, an algorithm, and the signature we obtained in the sign method and returns a true or false indicating if the signature is valid.

Ok, the final code for this post is a simple method to execute a test on this code.

using BlogSandbox.command;
using BlogSandbox.encryption;
using System;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;

namespace BlogSandbox
{
    class Program
    {
        static void Main(string[] args)
        {
            string textToSign = "Sign this text";
            byte[] signature = DigitalSignature.SignMessage(
                        StoreName.My,
                        "CN=TestCertificate", 
                        Encoding.UTF8.GetBytes(textToSign));
            bool verified = DigitalSignature.VerifySignature(
                        StoreName.My,
                        "CN=TestCertificate", 
                        Encoding.UTF8.GetBytes(textToSign),
                        signature);
            Console.WriteLine("Verified? " + verified);
            Thread.Sleep(20000);
        }
    }
}
That's it... you now have a small library that you can use to sign data.  To make the library more robust, I recommend adding methods to support using "stream" based messages so that you can handle files directly.  Additionally, you will probably want to handle exceptional cases, which I have not done here for brevity and clarity.

In the next few blog posts (I will try to wrap them up over the next few weeks) I will show you how to handle the symmetric encryption of your message, followed by the asymmetric encryption of the keys.  Once I have done that, I will go over how to put it all together to create a single message that you can send across the network/intranet/internet.

Wednesday, October 3, 2012

Information Security - Book Review

As part of the requirements of maintaining my Certified Secure Software Lifecycle Professional (CSSLP) certification from ISC2, I have to earn 15 Continuing Professional Education (CPE) credits per year.  As part of this requirement, I wrote a book review to be published on their site and I thought I would share it here as well for anyone interested.  I hope it is useful to someone.

Title: The Basics of Information Security
By: Jason Andress
Publisher: Syngress
Publication Date: August 1, 2011
Print ISBN-13: 978-1-59749-653-7
Web ISBN-13: 978-1-59749-654-4

Review (Overall rating 4 out of 5):

Jason Andress’ book, “The Basics of Information Security”, provides a high level overview of the primary risks security specialists need to be aware of.  The book is well written and discusses the issues in more of a conversational style, which keeps the reader engaged.  As the title of the book indicates, the content is higher level and does not delve deeply into the specifics about how to specifically mitigate security flaws, but rather focuses on making the reader more aware of the issues.  The book provides real world examples that help the reader to understand each of the security domains much more clearly.  Additionally, at the end of each chapter, there are several exercise questions that helps ensure the reader has a solid understanding of the topic.

While all of the chapters are necessary some of the topics are much more interesting and contained more useful content than others.  Specifically, the chapter discussing Physical Security, while relevant, probably could have been shorter as many of the points discussed were rather obvious.  Additionally, the book would have been better if the author delved a little more deeply into some of the more interesting content, like Cryptography.  While this book’s focus was not specifically on software development, it would have been much better if it included a chapter on the Software Development Life Cycle and how important it is to build security in from scratch as opposed to bolting it on later.

One of the most informative chapters in this book was the one on “Authorization and Access Control”.  This chapter outlined several approaches and provided a very clear and understandable discussion about them.  In particular, the author did an exceptional job clearly explaining the Bell-LaPadula, Biba, and Brewer and Nash models of access control.  Many authors provide the details, but do not provide examples that make these concepts understandable, but this author does and he does it well.

Overall, this book provides a really good high level, conceptual overview of information security and the issues security professionals are faced with on a day to day basis.  The author’s conversational style is very engaging and keeps the reader focused on the topic; he is careful not to provide too much mundane detail which would just cause the reader to lose interest.  This book is a great read for anyone that is just starting to study for the CSSLP as it provides a very nice overview of the topics in the exam.  This book does not dig in too deeply to the topics, however, and should only be the start of one’s study.  That said, the book does provide examples at the end of each section that will help ensure that the reader understands the topics, which will help anyone studying for the exam to ensure they have a solid understanding of the material.  Additionally, this book is a great read for anyone that thinks they might want to start a career in information security as it outlines the main topics and provides the reader with a sense of what they could expect in such a job.

Tuesday, September 25, 2012

C# - Security - Cryptographic Agility

When developing any software it is really important to try and make your software as flexible as possible - loosely coupled designs with highly configurable components results in a much more sustainable and less fragile application.  Of particular concern in modern software is security; the most secure algorithms used in today's software are not the most secure algorithms in tomorrow's software.  In an effort to reduce hardcoding the cryptographic algorithms utilized within an application should be configurable leading to a concept known as Cryptographic Agility.  In the .Net world this is accomplished using the machine.config file stored within the .Net installation.  There is a great article that discusses how this is implemented and how to use it here, so I will not rehash it in this post.  There is no doubt that this is the preferred mechanism for implementing cryptographic agility in windows .Net applications as the machine.config file is managed by the administrators for the machine and are not generally accessible to all users on the machine (thus preventing just anyone from changing the algorithm to a less secure algorithm).  However, not all all deployment scenarios are necessarily able to accommodate these changes (maybe b/c it is a shared hosting site).  Thus, in this post I want to provide one alternative that allows you to take advantage of the machine.config file, but still offer an alternative for those times when the machine.config file is out of your control (or for those rare use cases where you need to override the machine.config).

One option is to use the application's properties to define the default algorithms if that machine.config file does not contain them. One possible scenario, and the one I will use here, is that all of your base crypto files/utils can extend from a base class that uses a static constructor to ensure that either the machine.config values exist OR that they are added to the CryptoConfig configuration from a property file.  There are other ways to initialize the CryptoConfig, of course, but this one is easy and works well.  However, it is important to note, that if an exception is thrown within the static constructor, that the application will NOT terminate and the class file will be left in an unusable state, so please make sure you code for this.  Some might consider this a bad decision (to use this static constructor), but I think it depends on your situation - in my case, if this fails that application can't be used, thus I check for this and fail out gracefully.

Now on to the example.  First create a base class from which your others can extend:

public abstract class Cryptography
{
     static Cryptography()
     {
     }
}

Before we fill in the static constructor, let's add a couple methods that we will be using within the constructor.  The first method will be the one used to register with CryptoConfig the algorithm defined in the properties file.  This will be used when the machine.config file is missing the mapping or when there is a desire to override it (more on this option shortly).

private static void SetAlgorithm(
  string name, string cryptoType)
{
 CryptoConfig config = new CryptoConfig();
 Type type = Type.GetType(cryptoType);
 CryptoConfig.AddAlgorithm(type, name);
}

The next method is the main method to check if the value is in the machine.config file, it it is not (the call to CreateFromName will return null), then it will call SetAlgorithm to set the type based on what is in the configuration file.  You must ensure there is a value in the configuration file as this class doesn't handle the situation where it is not (or add your own defaults to this class).

private static void SetConfiguration(
 string name, string type)
{
 object algorithm = CryptoConfig.CreateFromName(type);
 if (algorithm == null)
 {
  SetAlgorithm(name, type);
 }
}

Finally, back to the static constructor.  In order to allow overrides, we use a property to indicate that we should use the local settings rather than machine.config values.  In order to reduce code, I am using an action delegate to define that the method "SetAlgorithm" should be used when the UseLocalSettings property is set to true; thus, when this property is true, even if the algorithm is configured in machine.config, the local setting will be used instead.

static Cryptography()
{
 Action action = SetConfiguration;
 if(Properties.Settings.Default.UseLocalSettings)
 {
  action = SetAlgorithm;
 }
 action("Hash256", Properties.Settings.Default.Hash256);
 action("Hash512", Properties.Settings.Default.Hash512);
 action("Symmetric", Properties.Settings.Default.Symmetric);
 action("Asymmetric", Properties.Settings.Default.Asymmetric);
}

Edit: Thanks to a post from a google+ follower (Chris Eargle) I realized there was one omission (the generics on my Action) and a more elegant way to set the action method (ternary expression).

Action<string, string> action = 
     Properties.Settings.Default.UseLocalSettings ? 
           SetAlgorithm : SetConfiguration;

Finally, you just need to set these properties in your app.config file.  Each of the hash algorithms are strings and the UseLocalSettings property is a bool.  Example settings for the algorithm's values are as follows (for .Net 4.0):

Hash256=System.Security.Cryptography.SHA256CryptoServiceProvider, 
 System.Core, Version=4.0.0.0, Culture=neutral, 
 PublicKeyToken=b77a5c561934e089
Hash512=System.Security.Cryptography.SHA512CryptoServiceProvider, 
 System.Core, Version=4.0.0.0, Culture=neutral, 
 PublicKeyToken=b77a5c561934e089
Symmetric=System.Security.Cryptography.AesCryptoServiceProvider, 
 System.Core, Version=4.0.0.0, Culture=neutral, 
 PublicKeyToken=b77a5c561934e089
Asymmetric=System.Security.Cryptography.RSACryptoServiceProvider, 
 mscorlib, Version=4.0.0.0, Culture=neutral, 
 PublicKeyToken=b77a5c561934e089

I hope someone finds this useful... Feel free to comment if you have suggestions on how this can be improved or if you have questions about the content.

Thursday, September 20, 2012

C# - LINQ on dates

I recently had a need to get all the days in a month that were on a Monday (so for 9/2012 - the days are 3, 10, 17, 24).  Still being new to C#, LINQ was not my first thought... hell, it wasn't even one of my thoughts. I did a little googling to see if any of the current APIs did this already (I figured there was no reason to re-invent the wheel, right).  While I didn't find any APIs, I did find some ideas.  I found some similar examples using LINQ... so, I started playing around with them and this is what I ended up with.

The first part required an iteration of the days in the given month... for this, I used something else that I learned (and is no less cool) - the yield operator.  This is not something we have in the java world and I would really love to have it!
private static IEnumerable EnumerateDaysInRange(
                                   DateTime start, DateTime end)
{
    for (var day = start.Date; day <= end; day = day.AddDays(1))
 yield return day;
}
With this enumeration, I can now build a "from" component in a LINQ satement.
public static List DetermineDaysWeekly(
     Payee payee, 
     DayOfWeek dayOfWeek, 
     int month, 
     int year)
{
    DateTime firstDayOfMonth = new DateTime(year, month, 1);
    DateTime lastDayOfMonth = new DateTime(year, month, 
        DateTime.DaysInMonth(year, month));
    IEnumerable dates = 
     from date in 
            EnumerateDaysInRange(firstDayOfMonth, lastDayOfMonth)
   where (date.DayOfWeek == dayOfWeek)
   select date.Day;
    return dates.ToList();
}
All I am doing here is setting the date for the first day of the month and the last day of the month to pass to the previous function I built above (EnumerateDaysInRange).  The where clause simply checks if the day of the week during that iteration is the one we want and if it is (the select) captures the Day property on the date.  The days are all added to the IEnumerable object, which I convert to a list in my return statement.

Pretty simple really.  Now that I know more about LINQ, I will be sure to look for more places where this could be useful.  In this particular use case, I wasn't too worried about performance, but if I were, I would really need to take some time to research the performance of LINQ.  If anyone has thoughts regarding performance, or anything else for that matter, feel free to leave a comment.

Saturday, September 15, 2012

C# - Dynamic Factory for Commands

Factories are a useful and important mechanism in programming.  I have written many of them in Java and recently created one for Commands in C#.  There are many ways that a factory can work to provide you with implementations you request, but the ideal one handles it dynamically.  Once a factory is built, you really shouldn't have to manually add the implementations to a map... this is error prone and harder to maintain.  Ideally, you would just be able to add a new class, recompile, and run.  Even better, if done properly, this can be done by simply adding the class to a folder and it is automatically picked up.  For this post, I have thrown together a very simplified example of a factory that automatically loads the classes at runtime and are obtainable through a command name.  This example serves as the basis for a command line interpreter where the command passed in is used to lookup the implementation.

To start with, let's create an interface for Commands. For this example, I am using a base namespace of BlogSandox.
namespace BlogSandbox.command
{
    public interface ICommand
    {
        string CommandName { get; }
        string Execute(string input);
    }
}
All Commands will implement this interface and provide a command name (this is used to map the command to its instance).  To simplify all implementations, we will provide an abstract base class.
namespace BlogSandbox.command
{
    public abstract class BaseCommand : ICommand
    {
        private readonly string _commandName;

        protected BaseCommand(string commandName)
        {
            this._commandName = commandName;
        }

        public string CommandName
        {
            get { return _commandName; }
        }

        public abstract string Execute(string input);
    }
}
Now let's create a couple example Commands. Admittedly, these are pretty useless, but should help get the point across.
namespace BlogSandbox.command
{
    class EchoCommand : BaseCommand
    {        
        public const string NAME = "EchoCommand";
        public EchoCommand()
            : base(NAME)
        {
        }

        public override string Execute(string input)
        {
            return input;
        }
    }
}

namespace BlogSandbox.command
{
    class GreetCommand : BaseCommand
    {
        public const string NAME = "GreetCommand";
        public GreetCommand()
            : base(NAME)
        {
        }

        public override string Execute(string input)
        {
            return "Hello " + input + "!";
        }
    }
}
Now for the command factory.  This factory is going to register each instance using the "CommandName" provided by the implementing classes.  While this example doesn't have a "collision" detection (e.g. when 2 commands have the same name), it is not a bad idea to add one if you will be dealing with a lot of commands and especially if you will be making them pluggable.

namespace BlogSandbox.command
{
    public class CommandFactory
    {
        private readonly Dictionary _commandImplementations;
        private static volatile CommandFactory _commandFactoryInstance;
        private static object _syncRoot = new object();

        private CommandFactory()
        {
            _commandImplementations = new Dictionary();
            Initialize();
        }

        public static CommandFactory Instance
        {
            get
            {
                if (_commandFactoryInstance == null)
                {
                    lock (_syncRoot)
                    {
                        _commandFactoryInstance = new CommandFactory();
                    }
                }
                return _commandFactoryInstance;
            }
        }

        public ICommand GetCommand(string commandName)
        {
            return _commandImplementations[commandName.ToLower()];
        }

        private void Initialize()
        {
            // 1. get assembly
            Assembly asm = Assembly.GetCallingAssembly();

            // 2. get the list of all types in this assembly and iterate
            foreach (Type type in asm.GetTypes())
            {
                // we want the non-abstract implementations of ICommand
                if (type.IsClass && !type.IsAbstract)
                {
                    Type iCommand = 
                        type.GetInterface(
                          "BlogSandbox.command.ICommand");
                    if (iCommand != null)
                    {
                        // create an instance
                        object inst = 
                            asm.CreateInstance(type.FullName, true, 
                             BindingFlags.CreateInstance, null, null,
                             null, null);
                        if (inst != null)
                        {
                            ICommand commandInst = (ICommand)inst;
                            // make it case insensitive
                            string key = 
                                commandInst.CommandName.ToLower();
                            _commandImplementations.Add(
                                key, commandInst);
                        }
                        else
                        {
                            string errMsg =
                                "CommandFactory.Initialize(): Unable " +
                                "to properly initialize " +
                                "CommandFactory - there was a " +
                                "problem instantiating the class " +
                                type.FullName;
                            throw new Exception(errMsg);
                        }
                    }
                }
            }
        }
    }
}
The main thing to catch here is the use of the "Assembly" to find the classes and then load the ones that are of the appropriate type (e.g. non-abstract class that implements our command interface ICommand). To see this working, here is a simple main that you can add for a Console Application.  The sleep at the bottom keeps the window open long enough to see the results... of course, you could use a logger or other application type that doesn't close up at completion.
namespace BlogSandbox
{
    class Program
    {
        static void Main(string[] args)
        {
            CommandFactory factory = CommandFactory.Instance;
            Console.WriteLine("Echo Command: " + 
                factory.GetCommand(EchoCommand.NAME).
                    Execute("Repeat me"));
            Console.WriteLine("Greet Command: " + 
                factory.GetCommand(GreetCommand.NAME).
                    Execute("Paul"));
            Thread.Sleep(20000);
        }
    }
}
These commands are clearly very simplified, but I hope that you can see how this can be applied in your own use case.  In a full implementation that I wrote for work, the BaseCommand method had protected methods for performing validations on the commands, returned a CommandResponse object where errors could be added in a list or a successful response could be provided (such as returning a result of the action). Additionally, for building my commands I used a fantastic command line parser library.  I highly recommend this library as it really simplified taking in command arguments.

This simplified example really only touches on the factory for commands, but doesn't really discuss a good way to implement the commands, nor how to parse a command line.  In a future post, I will explore the Command Line Parser Library I used and try to build from this example so that you can see more of the whole picture.  I hope this helps someone out there!  As always, feel free to use my code - while not necessary, attribution in the form of a link back to this post is always appreciated!

Thursday, September 13, 2012

C# coolness - extension methods

This is a feature that I fell in love with in Groovy - the ability to add functionality to existing classes. This dynamic capability can really reduce your code footprint significantly with only moderate complexity!  I recently had a use case where I wanted to be able to split a string based on spaces (this was for command line parsing).  With a little assist from some code found on StackOverflow and this functionality, I had a quick and useful extension I could use in parsing out the command line.  This could still use a little work, but is pretty functional for most basic cases.

First - attribution.  The split code in this post was inspired by this response to a question on StackOverflow.

In order to create extension methods, you have to define your class as a public static class.  Extension methods are static methods and the first parameter is the type you are extending - here is the syntax: "this typeExtending varName".  This first snippet sets up a new Split method that takes in a delegate for how it should act on each character.

public static IEnumerable<string> Split(this string text, 
    Func<char, bool> internalFunction)
{
    int next = 0;
    for (int chr = 0; chr < text.Length; chr++)
    {
        if (internalFunction(text[chr]))
        {
            yield return text.Substring(next, 
                      chr - next).CleanString();
            next = chr + 1;
        }
        // process the last char differently b/c IF it 
        // is a quote, it will get left out (since 
        // internalFunction will return false since it 
        // never reaches the split character - unless a 
        // trailing space is added).
        else if (chr == text.Length - 1)
        {
            yield return text.Substring(next).CleanString();
        }
    }
}

Here is the implementation for the CleanString method (used in the above snippet).  Notice that this is also an extension method:

public static string CleanString(this string str)
{
    string returnStr = str;
    if (!String.IsNullOrEmpty(str))
    {
        returnStr = returnStr.Trim();
        returnStr = returnStr.TrimMatchingQuotes();
    }
    return returnStr;
}

Here is the implementation for the TrimMatchingQuotes (used in the above snippet).  This is again an extension method:


public static string TrimMatchingQuotes(this string input)
{
    // strings less than 2 chars don't have matching quotes 
    if ((input.Length >= 2) &&
        (input[0] == QUOTE) && 
        (input[input.Length - 1] == QUOTE))
    {
        return input.Substring(1, input.Length - 2);
    }
    return input;
}


Now for the final piece of goodness!  For splitting command lines that honor quotes (e.g. executable -t "some text") - please note, this does not work with quotes inside your quotes - I leave that to you if you need it!


public static IEnumerable 
    SplitStringHonorQuotes(this string str, char splitChar)
{
    bool inQuotes = false;
    return str.Split(character =>
                {
                    if (character == QUOTE)
                    {
                        // if we're in quotes, now we aren't
                        inQuotes = !inQuotes;
                    }
                    // don't split if inside a quoted section
                    return !inQuotes && character == splitChar;
                });
}


That's it, now you have some extension methods to help split your command line.  Drop all that code in a class like this:
 

using System;
using System.Collections.Generic;

namespace ProjectNamespace
{
    public static class StringUtils
    {
        // This constant is used in above code
        private const char QUOTE = '\"';
        // add above code here...
    }
}

Now, to use it:

// import your StringUtils class with extension methods
using ProjectNamespace;
...
string[] cmdArgs = 
   "-C command -t \"some text\"".SplitStringHonorQuotes(' ').ToArray();


I hope you found this post useful! Feel free to use this code as you wish... if you need a license, you can use the Apache license.  A link back to this post, while not required, would be appreciated.

Finally, I welcome constructive criticism on how this can be improved.  I am new to the .Net world, so I am still learning what C# has to offer.

Followers