Thursday, June 9, 2011

Silverlight 4 Value Converter Properties

An interesting problem I faced recently was how to give a Value Converter class access to "data" (strings, ints, bools, lists, collections, etc). I thought about this for a while, and I firstly figured I could probably give the Value Converter access to whatever data it needed through its own view model. I thought about this some more and decided wouldn't it be cool if I could just declare properties in my Value Converter class and bind those properties to data in my xaml's view model, thus keeping my Value Converter a fairly light object. At that time there wasn't much literature around suggesting that this was even possible, much less any examples, so I went about it my own way.

I had also been recently looking at binding to dependency properties (Silverlight 4 Custom Property Binding), so it was something I had fresh in my mind. I knew that to register a DependencyProperty the owner needed to inherit from the DependencyProperty base class. So as well as implementing the usual IValueConverter interface, I made my class inherit from DependencyObject like so:
public class CustomValueConverter : DependencyObjectIValueConverter 

I then declared a couple of dependency properties in my class; firstly a Dictionary<intstring> LookupDictionary and secondly a bool UpperCase , like so:
public static readonly DependencyProperty 
LookupDictionaryProperty = DependencyProperty.Register
(
    "LookupDictionary",
    typeof(Dictionary<intstring>),
    typeof(CustomValueConverter),
    null
);
 
public Dictionary<intstring> LookupDictionary
{
    get { return (Dictionary<intstring>)GetValue(LookupDictionaryProperty); }
    set { SetValue(LookupDictionaryProperty, value); }
}
 
public static readonly DependencyProperty UpperCaseProperty DependencyProperty.Register
(
    "UpperCase",
    typeof(bool),
    typeof(CustomValueConverter),
    null
);
 
public bool UpperCase
{
    get { return (bool)GetValue(UpperCaseProperty); }
    set { SetValue(UpperCaseProperty, value); }
}

The next thing I wanted to do was actually use the properties in my Convert method, so as an example I did something like this:
public object Convert(object 
value, Type targetType, object parameter, CultureInfo culture)
{
    string lookup = string.Empty;
    if (!(value == null || LookupDictionary == null))
    {
        if (value is int)
        {
            if (UpperCase)
                lookup = LookupDictionary[(int)value].ToUpper();
            else
                lookup = LookupDictionary[(int)value];
        }
    }
    return lookup;
}

That's basically all you need to be able use your converter in your xaml, and set values for the properties we have declared in it.

Here is the entire example of the Value Converter class example:
using System;
using System.Windows;
using System.Windows.Data;
using System.Globalization;
using System.Collections.
Generic;
 
public class CustomValueConverter : DependencyObjectIValueConverter
{
    public static readonly DependencyProperty LookupDictionaryProperty = DependencyProperty.Register
    (
        "LookupDictionary",
        typeof(Dictionary<int, string>),
        typeof(CustomValueConverter),
        null
    );
 
    public Dictionary<intstring> LookupDictionary
    {
        get { return (Dictionary<intstring>)GetValue(LookupDictionaryProperty); }
        set { SetValue(LookupDictionaryProperty, value); }
    }
 
    public static readonly DependencyProperty UpperCaseProperty = DependencyProperty.Register
    (
        "UpperCase",
        typeof(bool),
        typeof(CustomValueConverter),
        null
    );
 
    public bool UpperCase
    {
        get { return (bool)GetValue(UpperCaseProperty); }
        set { SetValue(UpperCaseProperty, value); }
    }
 
 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        string lookup = string.Empty;
        if (!(value == null || LookupDictionary == null))
        {
            if (value is int)
            {
                if (UpperCase)
                    lookup = LookupDictionary[(int)value].ToUpper();
                else
                    lookup = LookupDictionary[(int)value];
            }
        }
        return lookup;
    }
 
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
 
}}

Monday, May 16, 2011

Makecert, X509 Certificates and RSA

Makecert, X509 Certificates and RSA

So there is a lot of articles out there about x.509 certificates, RSA and the makecert tool but nothing really that ties it altogether. Given these articles I am not going to focus on the individual parts, but rather focus on using all the bits together to do X509 certificate key based RSA provider encryption and decryption using C#.

Generate Some Certificates

Here is the combination of the makecert and pvk2pfx command lines I used to generate my certificates:
1.      makecert -n "CN=Nicks Certificate Authority" -cy authority -a sha1 -sv "C:\temp\cert\nick_ca.pvk" -r "C:\temp\cert\nick_ca.cer"
2.      makecert -pe -n "CN=Nicks Dev" -a sha1 -sky exchange -eku 1.3.6.1.5.5.7.3.1 -ic "C:\temp\cert\nick_ca.cer" -iv "C:\temp\cert\nick_ca.pvk" -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 -sv "C:\temp\cert\nick_dev.pvk" "C:\temp\cert\nick_dev.cer"
3.      pvk2pfx -pvk "C:\temp\cert\nick_dev.pvk" -spc "C:\temp\cert\nick_dev.cer" -pfx "C:\temp\cert\nick_dev.pfx"
There are plenty of articles out there talking about the makecert and pvk2pfx tools so I wont go on too much about those. Suffice to say, step 1 creates a certificate authority with private key, step 2 creates a certificate for use based on the authority with private key, and step 3 takes the certificate and key from step 2 and wraps them into personal information exchange (pfx) file. You will also notice that I am generating my cer, pvk and pfx files into the "C:\temp\cert\" directory. I haven't bothered about importing these files into my certificate stores, if you are interested in that there are a number of other articles out there that you can refer to, along with the syntax for the makecert and pvk2pfx.

Use the Certificates

Now we're got the techy stuff out of the way, its now time to actually put these certificates to work. The following code shows how we get an instance of our certificate, and cast it to an RSA provider for further use in our C# code:
string path = "C:\\temp\\cert\\nick_dev.pfx";
X509Certificate2 certificate = new X509Certificate2(path, string.Empty);
RSACryptoServiceProvider provider = (RSACryptoServiceProvider)certificate.PrivateKey;

By the way, I am in no way advocating that my code is best practice I am just illustrating roughly how to get the job done. Notice that the X509Certificate2 constructor takes two parameters, the first is the path and the second is the password, with this particular overload signifying that we are loading a pfx file. No password is provided as we didn't specify one when we created our certificates, I would recommend you do use a strong password, but again you can look at the numerous articles out there for makecert and pvk2pfx to help you with this option.

Encrypting and Decrypting
Ok we've already got our RSA provider so you can probably work it out from here or even look at the again numerous articles on RSA encryption and decryption to help you, but since I promised I would tie all the technologies together I better fulfil my end of the bargin and give you a quick overview of how to do the encryption and decryption.
So, here is the code for encryption:
public static string RSAEnc(RSACryptoServiceProvider provider, string plain)
{
    StringBuilder cipher = new StringBuilder();
    int cur = 0;
    while (cur < plain.Length)
    {
        string ss = plain.Substring(cur);
        if (ss.Length > 86) ss = ss.Substring(0, 86);
 
        List<byte> buffer = new List<byte>();
        foreach (char c in ss.ToCharArray())
            buffer.Add((byte)c);
        byte[] result = provider.Encrypt(buffer.ToArray(), true);
        foreach (byte b in result)
            cipher.Append(b.ToString("X2"));
 
        cur += 86;
        if (cur < plain.Length) cipher.Append("+");
    }
    return cipher.ToString();
}

And for decryption:
public static string RSADec(RSACryptoServiceProvider provider, string cipher)
{
    StringBuilder plain = new StringBuilder();
    if (!string.IsNullOrEmpty(cipher))
    {
 
 
        foreach (string ss in cipher.Split('+'))
        {
            byte[] buffer = new byte[ss.Length / 2];
            for (int cnt = 0; cnt < ss.Length; cnt += 2)
                buffer[cnt / 2] = Convert.ToByte(ss.Substring(cnt, 2), 16);
            byte[] result = provider.Decrypt(buffer, true);
            foreach (byte b in result)
                plain.Append((char)b);
        }
    }
    return plain.ToString();
}

There you go, simple as that.

Wednesday, March 30, 2011

Silverlight 4 Custom Property Binding

A common scenario you might encounter is wanting to create a bindable property on a custom control. The way we do this is using a static DependencyProperty member as our backing field. Below is an example of a CustomTextBox with a string CustomString property:

using System.Windows; 
public class CustomTextBox : System.Windows.Controls.TextBox 
{
    public static readonly DependencyProperty CustomStringProperty = DependencyProperty.Register
        (
            "CustomString",
            typeof(bool),
            typeof(CustomTextBox),
            null 
        );
 
    public string CustomString
    {
        get { return (string)GetValue(CustomStringProperty); }
        set { SetValue(CustomStringProperty, value); }
    } 
}
 
You can now use the CustomTextBox in your XAML, and bind directly to the CustomString property.

Just a simple example to illustrate how its done. If you want more information on how it all works, check out the MSDN documentation.