Simon Tatham’s Portable Puzzle Collection for Windows Mobile

July 29th, 2007

Screenshot of Galaxies puzzle game running on a Windows Mobile deviceLast week I came across Simon Tatham’s website via a blog posting by Jon Skeet. One of the interesting finds on his website was his Portable Puzzle Collection. This is a series of approximately 27 puzzles which have been architected to be easily ported to new platforms. At present Mac OS X, Unix (using GTK as the GUI toolkit) and Windows builds are officially supported.

Dariusz Olszewski has contributed patches for the existing Windows build to target Windows Mobile (Pocket PC 2003 or higher). I recently submitted a small patch to improve the Windows Mobile port to cope with devices which can dynamically change screen orientation. I have also locally modified the build script to compile with Visual Studio 2005 rather than Embedded Visual C.

I particularly like the Galaxies puzzle, it’s very simple, but addictive at the same time. It also exercises the right side of the brain, as you try to determine if a particular shape will have rotational symmetry.

These games are well worth a look at, and I encourage any C developer with a little spare time to look into improving the Windows Mobile port (source code can be obtained from a SVN repository at svn://ixion.tartarus.org/main/puzzles). These puzzle games are an ideal way to fill in a few spare moments of time.

Windows Mobile Tip: Peeking inside CAB files

July 28th, 2007

CAB files are the standard installation mechanism for Windows CE powered devices. Have you wondered what files have been installed by a given piece of software? Or what registry settings may have been overwritten during installation? If so, then this tip is for you.

CAB File Formats
A Microsoft CAB file is similar in nature to a common ZIP, or TAR file. They are a form of archive which contain one or more files. The individual files within a CAB file may have been compressed to reduce the overall size of the archive.

This archive file format has been re-purposed for application installation on Windows CE devices, by specifying a file with a special name that outlines the tasks required to install a given software package. This list of tasks will typically include decompressing and copying various files onto the PDA, but may also contain instructions to configure registry settings, or install shortcuts into the start menu etc.

Over the years the precise format of these files has changed. For a while the Windows Mobile Pocket PC and Smartphone platforms had incompatible CAB file formats. This has been resolved since the Windows Mobile 5.0 release which brought about a “unified” CAB file format for both platforms.

The older style CAB files had the list of setup instructions listed in a binary formatted file. The only information I am aware of on the structure of these CAB files is some reverse engineered documentation produced by the developers of the cabextract project.

The newer style CAB files have the list of setup instructions listed in an XML file called _setup.xml. It is this particular format that I will discuss here.

Extracting the contents of CAB files
On a desktop PC there are a number of ways you can extract the individual files within a CAB file. These include:

  • expand.exe – the Microsoft File Expansion Utility is a command line application present on all Windows machines. Specifying the name of a CAB file will cause the CAB file to be extracted into the current directory.
  • explorer.exe – by default most recent versions of Windows have an explorer shell extension which enables users to browse the contents of a CAB file by simply double clicking on it (as seen in the screenshot).
  • Winzip – many third party archive utilities will associate themselves with CAB files and enable you to extract their contents.

If you extract the _setup.xml file you can confirm that it’s main element is <wap-provisioningdoc>. This is a WAP provisioning document, as documented in MSDN in the Configuration Service Provider section.

The particular subset of this file format used by typical CAB files is fairly straight forward to follow, even without referring to the documentation. The _setup.xml file will enable you to determine the proper file names for the other files within a CAB file, and more importantly where they are installed to. One thing to be aware of is the use of macro Strings such as %CE2% to cope with internationalisation within file paths.

Possible uses of this tip
During development of an application, using this tip can be handy to verify that your CAB files are installing the desired files and settings. It is also useful when you have a CAB file which you have lost the original source code to, to determine what changes are made to the device.

The information would also be of use if you are developing an application to merge individual CAB files into one combined CAB file, such as the application discussed by Chris Tacke on his blog.

Random CAB fact of the day
Did you know that CAB files transfered via ActiveSync may be altered during the transfer process? If you have a CAB file which has been authenticode signed with a certificate, ActiveSync may strip off the certificate during the transfer process if it determines the connected device does not support signed cab files. This is something to be aware of, if you notice your CAB files won’t install if you download them across the network, but will if manually transfered via ActiveSync.

When is C# 2.0 not equal to C# 2.0?

July 27th, 2007

As I have mentioned previously I have only recently started learning about the .NET Micro Framework, as such I am constantly learning new things about this constrained development environment and today was no exception, here is what I learnt…

The lack of generics
I was investigating the use of the ExtendedWeakReference class, and as part of a test application I was putting together I thought it would be nice to make use of some generics. Generics were a new feature in C# v2.0 which enable you to produce efficient, reusable type safe code.

As the following example program demonstrates, you can make use of certain C# 2.0 features such as anonymous delegates when targeting the .NET Micro Framework. However any attempt to use generics will cause a build time error to occur.

using System.Threading;
using Microsoft.SPOT;
 
public class Program
{
  public static void Main()
  {
    // Configure a timer to print out a message to the debug window once
    // every 5 seconds. Notice that we use an anonymous delegate for the
    // TimerCallback delegate parameter. This is a C# 2.0 language feature.
    Timer t = new Timer(delegate(object o){ Debug.Print("Hello World!"); },
                                  null, 0, 5000);
 
    // Place the main thread into an infinite sleep. The
    // timer callbacks will occur on a separate thread.
    while (true)
      Thread.Sleep(Timeout.Infinite);
  }
}

If you do attempt to use generics within your code the C# compiler will execute successfully (i.e. csc.exe indicates no errors in the build log) but the Meta Data Processor (MetaDataProcessor.exe) which runs automatically after the C# compiler will produce the following error:

METADATAPROCESSOR: Error MMP0000: CLR_E_PARSER_UNSUPPORTED_GENERICS

The Meta Data Processor is the utility which converts assemblies from the standard PE Executable file format (as used on the desktop), into a smaller more efficient representation utilised by .NET Micro Framework devices.

My assumption here is that any C# v2.0 feature which ends up being a chunk of “compiler magic” which essentially converts your code behind the scenes into a form that would have been compatible with the V1.0 compiler is supported on the .NET Micro Framework. While features such as Generics, which required CLR changes in addition to compiler changes, are currently not supported by the .NET Micro Framework.

No support within the BCL to parse numbers
A typical programming task is to parse strings and convert them into numbers. Typically a .NET developer would use a static method within the Base Class Library such as Int32.Parse() to perform this operation.

However the numeric classes within the .NET Micro Framework BCL are pretty empty, and don’t include methods such as Parse. Likewise the System.Convert class does not exist. This means if you need to parse a number, you need to write the number parsing code yourself.

This issue has been discussed on numerous blogs and online forums. Some interesting coverage on this subject is as follows:

  • In a thread titled “Best way to convert string to float/double/decimal?” James Webster a Test Manager within the Microsoft .Net Micro Framework team mentions this is an issue which may be resolved in a later release of the framework. He also provides a quick suggestion as to a work around. This sample has a number of performance issues, which are then worked upon in the rest of the thread.
  • A post by Jens Kühner titled Number parsing with the .NET Micro Framework sounds very promising, however at present the download link to the source code appears to be broken.

While I was on Jens Kühner’s blog I noticed that he is currently writing a .NET Micro Framework book. He promises to release more details, and samples as time goes on. So his blog could be an interesting one to watch. It would be interesting to know how his book compares to Microsoft Press’s Embedded Programming with the Microsoft .NET Micro Framework.

The System.Math class
In a similar manor the System.Math class which provides various math functions is rather limited on the .NET Micro Framework’s version of the BCL. There are no SIN or COS functions for instance.

EmbeddedFusion recently released the source code for their “Ball-In-Maze” tutorial designed for their Tahoe Development Board. This lab was originally presented at MEDC 2007. Reading through the source code you come across a number of useful tips and tricks. Including an integer square root implementation, which I assume was done for speed.

Perhaps it is time to dust off my copy of Jack Crenshaw’s MATH Toolkit for REAL-TIME Programming book and develop a small support library of additional math functions.

Encrypt and decrypt the contents of a file created on a mobile device

July 26th, 2007

A screenshot of the example symmetric encryption application I wroteEncrypting the contents of a file is a common task, especially with configuration files which may contain sensitive passwords, or database connectivity information.

Recently I discussed symmetric and asymmetric encryption support within .NET Compact Framework v2.0. These blog entries were heavy in theory and light on actual sample applications.

Microsoft’s 70-540 exam covers knowledge about encryption by outlining a couple of common usage scenarios and expecting candidates are capable of implementing them. One such task is the ability to encrypt and decrypt the contents of a file and this blog entry covers an example implementation of this.

How to use the sample application
The main user interface is a single form. By making selections in the combo boxes at the top of the form you can select the required encryption algorithm and key size.

Whenever you change key sizes, a random encryption key is generated for you and this is inserted into the key text box. If you have a message encrypted with a specific encryption key, you can type it into the key text box manually.

To create an encrypted text file, type your message into the textbox at the bottom of the form and tap the encrypt button. A file save dialog box will appear to ask you where you want to save the encrypted file.

To decrypt a text file, tap the decrypt button and a file open dialog box will appear to ask you to select a file to decrypt. Once you have selected one an attempt will be made to decrypt the message using the encryption key present within the UI, and if successful the cleartext message will be displayed in the textbox.

If you use Pocket Word to open the text files you have encrypted, you should see that they contain no human readable content and simply contain a “garbled mess”. You should only be able to recover your encrypted message by configuring identical encryption parameters within the GUI again and pressing the decrypt button.

How it works
The process of implementing symmetric encryption within the .NET Compact Framework has been covered before, so please refer to that blog entry for technical details on the implementation. The source code of the sample application is also available, and is heavily commented to describe what is happening at each stage of the process.

A high level overview of how this application performs encryption of text files is as follows:

  1. An instance of a class which derives from SymmetricAlgorithm is created.
  2. The LegalKeySizes property is read to determine a list of valid key sizes.
  3. The KeySize and Key properties are configured with the desired values.
  4. The IV property is configured with the desired value (and optionally the BlockSize property is altered).
  5. A FileStream instance is created to allow access to the file.
  6. The FileStream is wrapped in a CryptoStream, which is then used instead of the original file stream (this is what performs the encryption/decryption).

Further work
Questions to ask yourself while reviewing the source code of this sample include:

  • How does a CryptoStream know if it is encrypting or decrypting data?
  • How can I verify if a given key size is valid for the selected encryption algorithm?
  • What exceptions may be thrown during decryption if an incorrect key is utilised?
  • What object oriented concept makes it easy to switch between different symmetric encryption algorithms with only minor code changes?

This sample application only demonstrates the use of symmetric encryption algorithms. As an exercise left to the user, see if you can alter the sample application to use asymmetric encryption by using the RSACryptoServiceProvider class. As part of your solution you should figure out how to export and import the public part of your public/private key pair, so other devices can read your encrypted messages.

The source code for the sample application can be downloaded.

Handling GPIO Interrupts within the .NET Micro Framework

July 25th, 2007

My previous .NET Micro Framework example demonstrated how to determine the state of a GPIO input signal. This blog entry outlines how to implement an improved application which instead makes use of an interrupt event handler, for improved performance and power efficiency.

The problem with the InputPort based example was that it utilised a polling mechanism to constantly determine the current state of the GPIO port, this mode of operation is not ideal for a number of reasons, including:

  • Power Management – The polling implementation may become a busy loop, spinning around as quickly as possible, burning CPU cycles to check the state of the input which only occasionally changes state.
  • Responsiveness – A common resolution to the power management issue is to only periodically probe the hardware. The example application from the last blog entry sampled the GPIO state once per second. This has the side effect of introducing latency, since we will only detect a change in state once the current delay has completed. We may also miss a change completely if it happens too quickly.

To resolve some of these issues we can utilise the InterruptPort class. This class derives from the InputPort class mentioned in the previous blog entry, and hence by default inherits all of the InputPort’s properties and functionality.

The main difference is an additional constructor parameter which specifies when an ‘OnInterrupt’ event associated with the port should fire.

Determining when the interrupt should trigger
The additional constructor parameter specifies the conditions under which the interrupt should trigger. You can use one of the following Port.InterruptMode enumeration values:

  • InterruptEdgeBoth – The interrupt is triggered on both rising and falling edges.
  • InterruptEdgeHigh – The interrupt is triggered on the rising edge.
  • InterruptEdgeLow – The interrupt is triggered on the falling edge.
  • InterruptEdgeLevelHigh – The interrupt is triggered whenever the input signal is high.
  • InterruptEdgeLevelLow – The interrupt is triggered whenever the input signal is low.

Clearing Interrupt flags
Edge interrupts trigger when the specified signal transition occurs and automatically re-enable themself, ready to trigger on the next state transition. Level based interrupts however behave slightly differently.

Whenever a level interrupt (InterruptEdgeLevelHigh or InterruptEdgeLevelLow) is triggered it sets a flag which disables the interrupt from re-triggering until the flag is explicitly cleared by means of the ClearInterrupt method.

The main purpose for this is to stop a constant stream of interrupts occurring when the specified level is reached on the GPIO signal. By disabling the interrupt once it has triggered, the software can decide when it wants to be interrupted again. When the ClearInterupt method is invoked, it is possible that the interrupt event handler will fire immediately, if the specified level is still held on the signal.

Example Application
The following is a simple example of how the InterruptPort class can be utilised to produce asynchronous behavior.

The main loop of the program, simply prints the message “House Keeping Ping…” to the debug console every 60 seconds. This is to provide an indication of when the main thread is running. In a typical embedded device this main loop may do menial house keeping tasks, such as timer management, and status LED flashing etc.

While the main loop is sleeping (or printing debug messages), the hardware is constantly monitoring the state of the GPIO_Pin_3 input (attached to the Select button within the Sample Emulator). Whenever the signal goes low, an interrupt is triggered, which causes our button_OnInterrupt event handler to execute on a second thread.

You will notice that button presses are detected immediately even while the main thread is sleeping, unlike the polling example which only detected the button press when the main thread woke up.

using System; 
using System.Threading; 
using Microsoft.SPOT; 
 
using Microsoft.SPOT.Hardware;namespace InterruptPortApplication 
{ 
  public class Program 
  { 
    public static void Main() 
    { 
      // Specify the GPIO pin we want to use as an interrupt 
      // source, specify the edges the interrupt should trigger on 
      InterruptPort button = new InterruptPort(Cpu.Pin.GPIO_Pin3, true, 
        Port.ResistorMode.PullDown, Port.InterruptMode.InterruptEdgeLow); 
 
      // Hook up an event handler (delegate) to the OnInterrupt event 
      button.OnInterrupt += new GPIOInterruptEventHandler(button_OnInterrupt); 
 
      while (true) 
      { 
        // The main thread can now essentially sleep 
        // forever. 
        Thread.Sleep(60 * 1000); 
        Debug.Print("House Keeping Ping..."); 
      } 
    } 
 
    static void button_OnInterrupt(Cpu.Pin port, bool state, TimeSpan time) 
    { 
      // This method is called whenever an interrupt occurrs
      Debug.Print("The button is pressed"); 
    } 
  } 
}

The three parameters in the GPIOInterruptEventHandler delegate type are as follows:

  • pin – a reference to the pin that caused the interrupt to occur. This is useful because you can hook up the same event handler to more than one InterruptPort instance.
  • state – the logic level of the GPIO signal when the interrupt occurred.
  • timestamp – a relative time-stamp which allows you to accurately determine when the interrupt occurred.

Performance
The InterruptPort class is not designed for use in hard real time applications. In my mind it is more a Deferred Procedure Call (DPC) implementation triggered by hardware events than a true Interrupt Service Routine (ISR).

Since I have no physical .NET Micro Framework hardware yet, it is a bit difficult for me to tell exactly how the performance characteristics of interrupt handlers within the .NET Micro Framework stack up. This is defiantly an area I would like to characterise further once my hardware arrives.

In the mean time here are some links to low level performance related material that I have managed to find. Both articles are written by Chris Tacke and give an excellent insight into the performance characteristics of the .NET Micro Framework (and managed code in general) for embedded development.

Asymmetric Key Encryption on the Compact Framework

July 24th, 2007

Asymmetric key encryption is useful for use in exchanging data over insecure communication channels. This is due to the use of separate keys for encryption and decryption. This blog entry follows on from the previous one on symmetric key encryption and discusses how to utilise asymmetric key encryption within a .NET Compact Framework application.

Asymmetric Encryption classes within the .NET Compact Framework
The .NET base class library provides Asymmetric Encryption classes within the System.Security.Cryptography namespace. They all derive from the AsymmetricAlgorithm base class.

The .NET Compact Framework base class library provides the following asymmetric encryption classes

  • RSACryptoServiceProvider – This is the .NET implementation of the RSA algorithm named after its three creators – Ronald Rivest, Adi Shamir and Leonard Adleman. It was developed in 1977. This is a wrapper around an unmanaged algorithm implementation provided by the Windows CE Crypto API.
  • DSACryptoServiceProvider – This class is used for digitally signing messages to ensure that they are not tampered with during transit. This is also a managed wrapper around unmanaged code. Since digital signatures and hashing are not part of the current topic I will not discuss this class any further.

Common Asymmetric Algorithm properties
When dealing with the encryption aspect of these crypto service providers there are only a couple of properties of interest defined on the AsymmetricAlgorithm base class:

  • KeySize – the size of the secret key used by the asymmetric algorithm in bits. These are typically much larger than symmetric keys. For example RSA as implemented in the .NET Compact Framework supports keys between 384 and 16384 bits. Setting this property affects the strength of the encryption process.
  • LegalKeySizes – an array of KeySizes objects which outline the range of key sizes supported by the current encryption algorithm.

Likewise there are only a couple of methods defined on the AsymmetricAlgorithm base class.

  • ToXmlString – exports a key pair in the form of an string containing an XML document.
  • FromXmlString – imports a key pair from a string containing an XML document.

You will notice there are no methods for encryption or decryption on the AsymmetricAlgorithm base class. Most of the useful methods (including those used for actual encryption) are actually defined on the classes which derive from AsymmetricAlgorithm.

The most useful methods defined on the RSACryptoServiceProvider class are as follows:

  • Decrypt – a method to decrypt data with the RSA algorithm.
  • Encrypt – a method to encrypt data with the RSA algorithm.
  • ExportParameters – returns a RSAParameters struct, which defines the RSA encryption key pairs (i.e. returns the same data as the ToXmlString method, just in a different format).
  • ImportParameters – imports a public key or key pair from the specified RSAParameters struct.

How to export and import key pairs
Once you have created an instance of the RSACryptoServiceProvider class it will generate it’s own public/private key pair. You can import and export the keys for storage purposes, or to transfer them to another device. In most cases you will probably want to only export the public key (since the private key should be kept a closely guarded secret).

When exporting the keys via the ToXmlString (as XML) and ExportParameters (as a RSAParameters struct) methods, you have the choice of exporting only the public key (false), or both the public key and private keys (true) via a boolean parameter.

The following code sample, demonstrates using these methods:

// Export the public key (pass in true to also export the private keys)
// from device A
RSACryptoServiceProvider rsa1 = new RSACryptoServiceProvider();
RSAParameters publicKey = rsa1.ExportParameters(false);
string publicKeyXML = rsa1.ToXmlString(false);
 
// ... transmit public key to another device ...
 
// Import the public key
// into device B
RSACryptoServiceProvider rsa2 = new RSACryptoServiceProvider();
rsa2.ImportParameters(publicKey);
rsa2.FromXmlString(publicKeyXML);

Please note that in the code sample I have demonstrated using both the XML and object based methods. In a typically application only one set of methods would be utilised.

Secure private key storage
Your application most likely needs to reuse the same public/private key pair a number of times. This means that once generated you will typically need to store your key pair in a secure manor.

The RSACryptoServiceProvider class includes the ability to save the keys in a secure manor by using the Crypto API CSP key container facility. You should seriously consider using this functionality to store private keys, as it is highly likely that it will be more secure than most solutions you will be able to create manually.

To store your private keys in a CSP key container, perform the following actions within your code:

The .NET Compact Framework then handles creating and retrieving keys automatically. The first time the code executes a unique public/private key pair will be generated and saved into the specific key container. In the future when the RSACryptoServiceProvider instance is created with the same key container name, the keys will automatically be retrieved.

// Create the CspParameters object and set the
// key container name used to store the RSA key pair.
CspParameters cp = new CspParameters();
cp.KeyContainerName = "MySampleKeyContainer";
 
// Create a new instance of RSACryptoServiceProvider 
// that accesses the key container "MySampleKeyContainer"
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp);
 
// Display the key information to the debug window.
Debug.WriteLine("Key added to container: \n  {0}", rsa.ToXmlString(true));

How to encrypt and decrypt data using Asymmetric encryption
The Encrypt() and Decrypt() methods both accept two parameters as follows:

  • rgb – a byte array containing the data to be encrypted or decrypted
  • fOAEP – a boolean flag. If true OAEP data padding is used, otherwise PKCS #1 v1.5 padding is used. This parameter doesn’t really matter as much, as long as encryption and decryption utilise the same value. Controlling this parameter becomes important in scenarios where one end of the encryption process is dictated by a third party system.

The following example demonstrates basic RSA encryption and decryption by providing a couple of small helper functions which will be useful within your own applications.

The methods encrypt (or decrypt) data passed to them in the form of a byte array and return another byte array containing the processed output. These methods utiilise the CSP Key Container storage mechanism to securely store the public/private key pair used to perform the encryption process.

using System.Security.Cryptography;
 
public byte[] Encrypt(byte[] data, string keyContainerName)
{
  // Configure the parameters to indicate the name of the
  // key container which contains our public/private key pair
  CspParameters csp = new CspParameters();
  csp.KeyContainerName = keyContainerName;
 
  // Create an instance of the RSA encryption algorithm
  // and perform the actual encryption
  RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(csp);
  return rsa.Encrypt(data, true);
}
 
public byte[] Decrypt(byte[] data, string keyContainerName)
{
  // Configure the parameters to indicate the name of the
  // key container which contains our public/private key pair
  CspParameters csp = new CspParameters();
  csp.KeyContainerName = keyContainerName;
 
  // Create an instance of the RSA encryption algorithm
  // and perform the actual decryption
  RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(csp);
  return rsa.Decrypt(data, true);
}

Please note that if the encryption and decryption code was running on two different devices, you would have to use the technique discussed in the “How to export and import key pairs” section to ensure that the decryptor had access to the public key.

A common request on newsgroup forums is for help in encrypting small amounts of text. Common problems encountered in this scenario include improperly converting the binary data produced by the encryption process back into a text string.

For this reason I have also provided the following helper functions which make it really easy to securely encrypt and decrypt text strings.

using System;
using System.Text;
 
public string EncryptString(string data, string keyContainerName)
{
  // Encrypt a string using the private key stored within the
  // specified key container
  byte dataToEncrypt[] = Encoding.UTF8.GetBytes(data);
  byte encryptedData[] = Encrypt(dataToEncrypt, keyContainerName);
  return Convert.ToBase64String(data);
}
 
public string DecryptString(string data, string keyContainerName)
{
  // Decrypt a string using the public key stored within the
  // specified key container
  byte dataToDecrypt[] = Convert.FromBase64String(data);
  byte decryptedData[] = Decrypt(dataToDecrypt, keyContainerName);
  return Encoding.UTF8.GetString(decryptedData);
}
 
// Example use
 
string myEncryptedString = EncryptString("This is my top secret message",
                                        "SampleKeyContainer");
...
string myDecryptedString = DecryptString(myEncryptedString,
                                         "SampleKeyContainer");

Now that I have provided some rather long discussions on symmetric and asymmetric key encryption within the .NET Compact Framework, I am finally ready to dicuss some practical uses of encryption. In the next few days I aim to cover off some of the encryption related aspects of exam 70-540.

Symmetric Key Encryption on the Compact Framework

July 23rd, 2007

There are two main types of encryption algorithms available within the .NET Compact Framework – symmetric and asymmetric encryption. This blog entry will discuss how to utilise symmetric key encryption, but first we have to outline the difference between Symmetric and Asymmetric encryption (I will discuss asymmetric key encryption in a future blog entry).

Symmetric and Asymmetric Key Encryption
Symmetric encryption algorithms (also known as ciphers) process plain text with a secret encryption key to create encrypted data (called cipher text). The same secret key is used to decrypt the cipher text back to plain text.

Asymmetric encryption (also known as public-key encryption) is a cryptography technique that uses public and private key pairs to encrypt and decrypt data respectably. The private key is a closely guarded secret, while the public key can be freely distributed over untrusted networks. You do not worry who has your public key (you could print it on a 100foot tall banner if you so desired), but you must keep your private key secret.

The two keys are mathematically linked; data encrypted with the public can only be decrypted by the private key and visa versa. So once data is encrypted you can safely assume only the intended recipient can read it.

The disadvantage of symmetric key encryption is that it assumes that the two parties involved have already agreed upon an encryption key in a secure manor. Any insecurity in the key exchange mechanism compromises the security of the data. Conversely the disadvantage of asymmetric encryption algorithms is that they are more computationally expensive and hence slower to work with.

A common technique is to use an asymmetric encryption algorithm to transfer a randomised symmetric encryption key that is then utilised to encrypt the rest of the communication process. SSL work this way for example.

Symmetric Encryption classes within the .NET Compact Framework
The .NET base class library provides Symmetric Encryption classes within the System.Security.Cryptography namespace. They all derive from the SymmetricAlgorithm base class which provides a set of common properties and methods. By deriving from a common base class it is easy for your application to switch among the different encryption algorithms with only minor code changes.

The .NET Compact Framework base class library provides the following symmetric encryption classes:

  • RijndaelManaged – Rijndael also known as Advanced Encryption Standard (AES) supports use of 128 to 256 bit keys (in 32bit increments). This is also the only symmetric encryption algorithm within the BCL which has a fully managed implementation.
  • DESCryptoServiceProvider – The Data Encryption Standard (DES) supports 56bit keys. This is vulnerable to cracking attacks due to relatively short key length by modern standards.
  • TripleDESCryptoServiceProvider – Triple DES is essentially three iterations of the DES encryption process. It utilises 156bit keys, but only 112 bits are effectively utilised for encryption.
  • RC2CryptoServiceProvider – This is an encryption standard designed to replace DES. It allows for variable length keys.

You will notice that many of the encryption classes end with the postfix “CryptoServiceProvider”. This is an indication that the encryption algorithm is implemented in native code, as part of the Windows CE Cryptography API. Internally the BCL classes are a thin wrapper over Platform Invoke code which access the actual encryption algorithms.

When deciding which encryption algorithm to use MSDN contains a good article called Performance Comparison: Security Design Choices” which compares the performance of the algorithms.

Common Symmetric Algorithm properties
All symmetric algorithms derive from the System.Security.Cryptography.SymmetricAlgorithm base class and share common properties, the most commonly used properties are described below.

  • BlockSize – Symmetric encryption algorithms work on blocks of data. The block size is the number of bits the encryption algorithm processes at a time.
  • IV – The initialisation vector (IV) for the encryption process. To prevent patterns forming in blocks of encrypted data, the second block of data is encrypted with the results of the first block and so on. Since the first block has no previous block the initialisation vector is used to obscure the first block of data.
  • Key – The secret key used for the symmetric algorithm. If not specified one is automatically generated. After encryption the key must be stored and transfered to the application which performs the decryption.
  • KeySize – The size of the secret key in bits. When you create a symmetric algorithm object, the runtime will choose the largest key size supported by the platform. You should only change this if the message recipient does not support the same key size.
  • Padding – One of the PaddingMode enumeration values. Determines how the algorithm pads out the last block if the plain text doesn’t fully consume the last block.

Likewise the SymmetricAlgorithim base class provides a number of abstract methods which support the basic encryption processes:

  • CreateDecryptor – This returns an instance of an object which implements the ICryptoTransform interface. A Cryptostream object can use this to decrypt a message.
  • CreateEncryptor – Similar to the CreateDecryptor method except the ICryptoTransform instance returned performs encryption
  • GenerateIV – Generates a random initialisation vector to be used with the symmetric algorithm and assigns it to the IV property.
  • GenerateKey – Generates a random key to be used by the symmetric algorithm and assigns it to the Key property.
  • ValidKeySize – Determines if the specified key size is valid for the current algorithm.

How to generate symmetric keys
To generate a random key you must use cryptographic strength random numbers. If your “random numbers” are guess-able (or have some form of pattern to them), you cripple the strength of your encryption. You should not use the System.Random class, because the random numbers it generates are not of cryptographic strength.

The easiest way to generate cryptographically strong random keys is to create an instance of your desired symmetric encryption algorithm and call the GenerateKey() method after setting the KeySize property to the desired key length. This will generate a random key of the required length and automatically assign it to the Key property, as the following example demonstrates:

SymmetricAlgorithim sa = new RijndaelManaged();
sa.GenerateKey();
byte[] key = sa.Key;

How to display encryption keys
Encryption keys are long sequences of random binary data and as such are difficult to display on a screen or to print out. Two common techniques for displaying keys (or general binary data) in a printable form are hexadecimal and Base64 formatting, as demonstrated by the following code sample:

// Converts the byte array into a hex encoded string
public string GetHexString(byte[] data)
{
  StringBuilder sb = new StringBuilder();
  foreach (byte b in data)
    sb.Append(b.ToString("X"));
  return sb.ToString();
}
 
// Converts the byte array into a Base64 encoded string
public string GetBase64String(byte[] data)
{
  return Convert.ToBase64String(data);
}
 
// Example of using the methods defined above
// to display encryption keys
SymmetricAlgorithm sa = new RijndaelManaged();
sa.GenerateKey(); // generates a random key
 
MessageBox.Show(GetHexString(sa.Key), "Key in Hex Format");
MessageBox.Show(GetBase64String(sa.Key), "Key in Base64 Format");

A hexadecimal string is easier to quote over a phone (since it only uses the characters 0 to 9 and A to F) however it will be longer than a Base64 string which also uses additional printable characters.

You should not use the System.Text.Encoding classes to convert an encryption key to a string. Since the encryption key is binary data, the key is not guaranteed to always consist of valid characters. Passing your encryption key through a text encoding process may corrupt the key, due to the encoding process merging characters and/or removing invalid characters.

How to encrypt and decrypt files by using Symmetric keys
The symmetric encryption algorithms within the BCL implement a streaming model. You create an instance of a CryptoStream and use it to wrap up access to an underlying stream.

The CryptoStream class transforms data (i.e. encrypts or decrypts) as it passes through to the underlying storage stream. The CryptStream class is an example of the decorator design pattern.

To encrypt or decrypt data symmetrically within your application you need to perform the following tasks:

  1. Create a stream to interface to the data you will be reading or writing to
  2. Create and initialise a SymmetricAlgorithm object
  3. Call CreateEncryptor() or CreateDecryptor() to create an ICryptoTransform object
  4. Create a CryptoStream by passing in your stream and ICryptoTransform object
  5. Read/Write to the CryptoStream as if it was your original data source

The following example demonstrates the encryption and decryption process by reading and writing the contents of an encrypted text file.

using System.IO;
using System.Text;
using System.Security.Cryptography;
 
// Configure the desired encryption algorithm parameters
SymmetricAlgorithm sa = new RijndaelManaged();
sa.GenerateKey();
 
// Encryption Example
ICryptoTransform transform = sa.CreateEncryptor();
using (Stream outputStream = new FileStream(@"\encrypted.txt", FileMode.Create))
{
  // Wrap the output stream up with a CryptoStream
  // which performs the data encryption
  using (Stream cryptoStream = new CryptoStream(outputStream, transform, CryptoStreamMode.Write)
  {
    // Store data into the cryptoStream (which will encrypt it
    // and then pass it along to our outputStream for storage)
    using (TextWriter tw = new StreamWriter(cryptoStream))
      tw.WriteLine("Hello this my message to encrypt!");
  }
}
 
// Decryption example
transform = sa.CreateDecryptor();
using (Stream inputStream = new FileStream(@"\encrypted.txt", FileMode.Open))
{
  // Wrap the input stream up with a CryptoStream
  // which performs the data decryption
  using (Stream cryptoStream = new CryptoStream(inputStream, transform, CryptoStreamMode.Read))
  {
    // Read data into the cryptoStream (which will fetch encrypted
    // data from the inputStream and then decrypt it before returning
    // it to us)
    using (TextReader tr = new StreamReader(cryptoStream))
      MessageBox.Show(tr.ReadToEnd(), "Unencrypted Data");
  }
}

If you look at the contents of the encrypted.txt file on the PDA device you will notice that it looks like random data. You can not determine what the message is by looking at it.

The encrypted contents of the file is binary data. If you must place this contents into a textbox control within a GUI, or send it in an email etc, you will most likely have to encode it using one of the techniques discussed in the section above about displaying encryption keys.

Notice: Typically the encryption and decryption processes would be in different parts of the application, or even on different devices. In this case you would also need to come up with a mechanism which ensures both parts of the code utilise the same initialisation vector (IV) and key parameters. Otherwise you can not be able to successfully decrypt the message.

Google Gears CE progress (workerpool now works!)

July 22nd, 2007

I have been a little slack recently on my port of Google Gears to Windows CE powered devices. However progress is still being made and I feel that I am getting closer to a version which has all features fully functional.

I have checked in changes to the google-gears-ce SVN repository which enable the worker pool feature of Google Gears to operate correctly on Windows CE. Once again it was a minor bug fix once I tracked down the problem. Windows CE will not allow a window with a client rectangle of 0×0 pixels to be created. Google Gears was creating such a window for thread syncronisation purposes to enable it to pass asynchronous results back to the main GUI thread. The solution was to change the code to create a window of 5×5 pixels. Although the window now has a larger client rectangle, it is still invisible due to the window being created without the WS_VISIBLE window style being set.

I have also checked in an initial build script (build-ppc.bat) which attempts to build a Google Gears CE executable for Windows Mobile powered PDAs. At present this won’t even compile due to missing header files within the Windows Mobile SDK etc, but it’s a start down the road of my initial aim for this project.

The most significant outstanding bug still to be resolved, is the issue I am having around getting the offline mode to work. Obviously this is a major part of the google gears solution and it is a bit disappointing that it has held out on me for so long. The Asyncronous Pluggable Protocol implementation Google Gears utilises to hook into requests for http:// and https:// URLs, is failing to initialise due to some differences between the platforms. The good news is that it appears that I am not the only one finding this problem and it does look solveable. It may however require a far amount of new code to be written (rather than the existing bug fixes which have turned out to be one or two lines here or there).

Once this final hurdle is overcame, it should be fairly easy to tidy up a couple of minor lose ends and have a fully functional version of Google Gears working on Windows CE.

What device is my application running on?

July 21st, 2007

Windows Mobile comes in two main variants, traditionally called Pocket PC and Smartphone. If your application must run on both platforms, it may be necessary to detect at runtime what type of device your application is running on. This blog entry will discuss techniques .NET Compact Framework developers can use to achieve this.

Detecting the Platform
The .NET Compact Framework does not have any built in support for determining the type of device the application is running on, so we need to develop a small class library to query this information ourself.

The first platform we can check for is the desktop PC. We may want to determine if a user is attempting to run our Compact Framework application on their laptop, Tablet PC or Ultra Mobile PC (UMPC) for example.

// Returns true if the application is running on a
// desktop version of the Windows operating system
public static bool IsDesktopWindows
{
  get { return Environment.OSVersion.Platform != PlatformID.WinCE; }
}

As you can see it is reasonably straight forward to determine if we are running on a desktop version of Microsoft Windows. We simply query for the platform id of the operating system via the Environment.OSVersion property and return true if it does not equal Windows CE.

By switching the conditional around we can also detect if we are running on a device that utilises a Windows CE based operating system. This is what the IsWindowsCE property does, as shown below.

  // Returns true if the application is running on a
  // device powered by some form of Windows CE based
  // operating system.
  public static bool IsWindowsCE
  {
    get { return Environment.OSVersion.Platform == PlatformID.WinCE; }
  }

As discussed in my blog entry “Is Windows Mobile 6 powered by Windows Embedded CE 6.0?“, Windows CE is an operating system that can be further customised to develop particular variants, such as Windows Mobile. Once we know that a device is a Windows CE powered device, we can query the OS for some additional information which will help us narrow down the type of device even further.

  // Returns true if the application is running on a
  // Windows Mobile Standard (i.e. Smartphone) device
  public static bool IsWindowsMobileStandard
  {
    get
    {
      return IsWindowsCE()
        && (NativeMethods.GetPlatformType() == "SmartPhone");
    }
  }
 
  // Returns true if the application is running on a
  // Windows Mobile Professional (i.e. Pocket PC Phone
  // Edition) device. Also returns true for Windows
  // Mobile Classic devices (no cellular radio).
  public static bool IsWindowsMobileProfessional
  {
    get
    {
      return IsWindowsCE()
        && (NativeMethods.GetPlatformType() == "PocketPC");
    }
  }

The NativeMethods.GetPlatformType() method used in the last two properties is one which we will have to develop ourself. It utilises a Platform Invoke (PInvoke) call to access the SystemParametersInfo operating system API. By querying the SPI_GETPLATFORMTYPE system parameter we can get a string back which enables us to differentiate between the Pocket PC or Smartphone platforms. Since the implementation of NativeMethods.GetPlatformType() is rather long I have not included the source code here, please see the sample project available for download for its implementation.

Notice that as it stands our IsWindowsMobileProfessional property also returns a false positive, since it will return true if the device is a Windows Mobile Classic device (i.e. a Pocket PC without a cellphone). We will correct this issue in a couple of moments.

Detecting the Emulator
By querying yet another system parameter (SPI_GETOEMINFO) we can determine if our application is running on a physical device, or within a Device Emulator running on a desktop PC.

This can be a useful thing to tell. For example, you could disable device specific code (such as barcode scanner interfacing logic) while running within the emulator.

  public static bool IsEmulator()
  {
    return (NativeMethods.GetOEMInfo() == "Microsoft DeviceEmulator");
  }

Detecting device specific features
If possible you should detect specific device features (such as cellular radio presence, screen size or orientation) instead of detecting platform types. This will make your application more robust, since over time it is possible that some of the differentiating features between the platforms will disappear.

To differentiate between Windows Mobile Professional (with cellphone) and Windows Mobile Classic (without cellphone) devices, we will have to detect the presence of a cellular radio.

For some device features there are no nice APIs available to detect their presence. In this case you need to probe the device to determine if DLLs or registry keys specific to that device capability are present on a given device.

Prior to Windows Mobile 5.0 the recommended method to determine if a device had a built in cellular radio was to detect if a DLL called phone.dll was present within the device. This could be achieved as follows:

using System.IO;
 
public static bool HasPhone()
{
  return File.Exists(@"\Windows\Phone.dll");
}

With this additional method we can now alter our implementation of the IsWindowsMobileProfessional property to check that a cellular radio is present. Likewise we can create a new IsWindowsMobileClassic property which returns true only if HasPhone() returns false.

As the Windows Mobile platform grows, and new versions are released, the number of device features with standardised detection mechanisms typically improves. With Windows Mobile 5.0 or above, the OS provides us with a nice managed API we can call to determine if a cellular radio is present, as can be seen in this alternative implementation of the HasRadio() method.

using Microsoft.WindowsMobile.Status;
 
public static bool HasPhone()
{
  return SystemState.PhoneRadioPresent;
}

There are a number of other properties available within the SystemState class which can be used to detect other device features, such as a camera. If developing for Windows Mobile 5.0 or above it is defiantly worth looking into this class.

Detecting Platform Versions
Sometimes detecting that you are running on a Windows Mobile Professional device is not enough. You may desire to display a warning prompt for example, if you application is running on an operating system version newer than the one you officially support.

To do this you must use the properties we have developed above (IsWindowsMobileProfessional, IsWindowsMobileClassic etc) to determine the platform your application is running on and then compare the current operating system version number, obtained via the Envrionment.OSVersion property, against a list of known Windows CE versions for that platform.

For example with the Windows Mobile releases we know that the following Windows CE operating systems were utilised:

Platform Release Windows CE kernel version
Windows Mobile 6 5.2
Wndows Mobile 5.0 5.1
Windows Mobile 2003 SE 4.21

So we could determine if an application was running on a Windows Mobile 5.0 Pocket PC by implementing the following check:

  if (IsWindowsMobileProfessonal 
    && Environment.OSVersion.Version.Major == 5
    && Envrionment.OSVersion.Version.Minor == 1)
  {
    MessageBox.Show("This is a Windows Mobile 5.0 Pocket PC");
  }

In the future
As discussed by Daniel Moth the next version of the .NET Compact Framework (v3.5) will have a new property within the SystemSettings class called WinCEPlatform. This property contains one of the following enumerated values:

  • WinCEGeneric
  • PocketPC
  • Smartphone

This will allow you to detect the platform your application is running on quite easily, without needing to write custom code as we have needed to do.

Example

I have put together a
small demonstration application which demonstrates how to detect the various platforms your .NET Compact Framework application may run on.

If you load the application up within Visual Studio 2005 you should be able to switch between the various platforms via the “Change Target Platform…” option within the “Project” menu. When you then launch the application within different emulators you should be able to see the code detecting which platform the application is currently running on.

If you have a need for detecting the type of platform your application is running on feel free to use a copy the “Platform.cs” file within your own projects.

Provide Help for an application

July 20th, 2007

Yesterday I provided a tip about using the context sensitive help feature within Windows Mobile. I finished the post with a gotcha, mentioning that it worked in few third party applications. This was due to the feature needing to be explicitly handled by the application developer. This blog entry is designed to discuss how .NET Compact Framework developers can implement integrated help within their own applications.

Integrating help into your application
Help within Windows Mobile is implemented by an application called peghelp.exe. This application is essentially a host for a web browser control which renders an HTML based help file.

There is typically one HTML help file per application. A special structure is used within the HTML file to determine where to split topics.

As a demonstration of how this works you may like to use the run dialog tip mentioned yesterday to run “peghelp \windows\calc.htm#Main_Contents”. This will view the help file associated with the built in calculator application.

Within the .NET Compact Framework the System.Windows.Forms.Help class helps wrap up this functionality and hide the specifics of launching peghelp.exe.

The ShowHelp method will display a specified topic within a help file. It can be invoked from within a button click event handler reasonably easily, as the following example demonstrates:

private void button1_Click(object sender, EventArgs e) 
  { 
  Help.ShowHelp(this, @"\windows\calc.htm#Main_Contents"); 
  }

Notice the ‘#’ character which seperates the path of the HTML help file and the name of the topic.

The first code sample is ideal for launching help from a button or menu item within our application. To launch your help by using the context sensitive help feature within the Windows Start Menu you need to listen to the form’s HelpRequested event as shown below.

private void Form1_HelpRequested(object sender, HelpEventArgs hlpevent) 
{ 
  Help.ShowHelp(this, @"\windows\calc.htm#pptskusecalculator"); 
}

By using unique topic names within the event handler associated with each form, you can obtain context sensitive help. In an advanced application you may even place conditional logic within your HelpRequested event handler. This enables you to display different help topics, depending upon the state of your user interface.

Creating your own help file
The help file for your application is a simple HTML file. However there are a couple of special tags you must utilise, in order for the help application to be able to split up your single file into multiple topics.

To create your first topic within an HTML help file, insert the following elements within the <body> element of the file.

<!-- PegHelp --> 
<a name="SomeTopic" title="SomeTopic" />    
 
.... HTML contents of topic goes here ....

The value of the name attribute (in this case set to “SomeTopic”) is the unique name for the topic, and is the value you should use to link to this topic.

The only special topic name that you should use is “Main_Contents” which should point to a topic which is suitable for use as a table of contents. Other than this topic name, you are free to use what ever names suit you.

To create additional topics, simply repeat this structure as many times as required. After the last topic it is very important to place another <!– PegHelp –> comment to mark the end of the help file. It is a common mistake for this comment to be missed and this has the effect of hiding the last topic.

Links between topics
Typically you will want to refer to other topics from within a topic. For example, at the bottom of each topic you may want to have a “see also” section, which lists other relevant topics.

To refer to another topic within your help file you use standard HTML anchor functionality, referring to the anchor name of the topic you want to jump to. This syntax is shown below, and is basically the path of your help file and the desired topic name seperated by a ‘#’ character.

<a href="MyHelpFile.htm#main_contents">Table Of Contents</a>

Development Tips
The parser used to break up a single file into multiple topics is not case sensitive, however it is sensitive to whitespace and changes in the format of the HTML elements. My recommendation is to utilise the same formatting of the <A NAME=”…”> and <!– PegHelp –> elements as shown in the examples in this blog entry. If you find that a topic is missing, or the content of more than one topic have become merged, double check that you have not accidently inserted additional whitespace between attributes etc.

When creating your help file you are most likely going to be using a desktop web browser which will show all your topics in one large page. When doing this it can become tricky to determine where one topic ends and another begins.

There is a special trick which will help resolve this issue. If you place an <hr> element immediately after each <!– PegHelp –> comment you will get nice divider lines separating each topic when you view your HTML help file within a desktop web-browser. However when you view the help file from within the Windows Mobile Help application they will have been removed.

Adding Keyword Search
Screen-shot showing search results including topics within the HTML help fileWithin the <head> element of your help file it can be handy to list a series of help topics and their matching keywords by using the <keyword> element. These keyword definitions are utilised by the Windows Mobile Find application when the user searches for help on a given topic (i.e. the find application does not search through your entire help file, it relies upon your explicitly listing all relevant keywords).

Some example keyword enteries may look like the following two example entries.

<keyword value="Puzzle;Games" title="Tetris 2000" href="tetris.htm#main_contents" />
<keyword value="High Score;Internet" title="Tetris 2000 High Score" href="tetris.htm#highscore"  />

The value element contains a list of keywords separated by semi colons, while the title element contains the title which will be displayed within the Find application when a match is found. Finally the href element contains the topic reference of the topic which should be displayed when a matching keyword is found.

Including Images
Images are displayed within the HTML help file using standard <img> HTML elements. However there are a couple of limitations to be aware of. The documentation on MSDN states that all images must be bitmaps with the *.2bp file extension. I believe that this document is purely a historical reference. I have had no problem using standard bitmaps with the *.bmp file extension, and I notice some of the included system help files do the same. You can not however utilise other image file formats, such as JPEGs or PNGs from within your help file.

URLs used to reference images are also relative to the \Windows directory, not the folder your HTML help file is located within.

Deploying your custom help file
Realistically your HTML help file must be located within the \windows directory. The help application can have problems if you place your help file in other locations, due to the need to use hardcoded file paths to refer to additional topics and images. These hard coded references will break if the user chooses to install your application in a different location, or your application is installed on a localised version of Windows Mobile (which will have different names for folders such as “My Documents”).

If you want the help file to show up in the main list of help files you should also place a shortcut link to your help file within the \windows\help folder. On a Windows Mobile 5.0 device this means that the help file will be accessable by selecting the “Help for Added Programs” entry within the help application’s table of contents.

If you are using a Smart Device CAB Project within Visual Studio 2005 to build your application cab you can include your help file within the CAB file by using the following procedure:

  1. Right click on your deployment project within the Solution Explorer and select “File System” from the “View” submenu.
  2. On the “File System on Target Machine” entry on the left hand side of the window, right click and select “Windows Folder” from the “Add Special Folder” submenu.
  3. Right click on the newly created “Windows Folder” directory and select “Folder” from the “Add” submenu.
  4. Type in “Help” and press enter
  5. Click on “Windows Folder” to select it
  6. On the right side of the window right click and select “File…” from the “Add” submenu
  7. Browse to your HTML help file and click “Open”
  8. Right click on the help file and select “Create Shortcut to ….”
  9. Rename the shortcut to remove the “shortcut to…” prefix
  10. Drag the shortcut to the “Help” subdirectory created above

Example Application
An example application which demonstrates how to create a properly formatted HTML help file, and launch it from a .NET Compact Framework application is available for download.

I have included the source code for the application, as well as a pre-built cab file. I would suggest you install the CAB file onto your device and have a play around with how it integrates the application’s help within the help application.

As a starter, try searching for “transport” or “chris” within the Find utility (you can find this within the “Programs” start menu option) and see how this produces links to the help file installed along with the application.

Revision History
26 July 2007 – updated the example application to include examples of using images within help topics in response to a recent forum thread.