This topic includes a sample implementation of theForefront Identity Manager Certificate Management (FIM CM) ICardInitialization interface, with discussion of each method. For more information on the requirements needed to develop an assembly implementing ICardInitialization, see Introduction to ICardInitialization.

Programming Model

To provide custom smart card initialization, you will need to create a class which implements the ICardInitialization interface, and implements its methods.

Object Lifetime

FIM CM instantiates objects of your custom class once, when the FIM CM server instance is first created by IIS. Your custom object instance will be maintained throughout the lifetime of the FIM CM server process, and will be destroyed when the FIM CM process is recycled by IIS.

When FIM CM starts up, it calls your implementation's Initialize method with the default administrative key and a custom string, both of which are configured in the profile template configuration.

Note:
For more information on configuring profile templates, see http://go.microsoft.com/fwlink/?LinkId=89698

This custom string is opaque to FIM CM, and can be used to pass custom data to your custom initialization object, such as information about connectivity to a custom hardware module.

Request Processing

The appropriate method in your custom object will be called each time the corresponding smart-card workflow step in the FIM CM is triggered. For this reason, each of your method implementations must be thread-safe and fully re-entrant.

Each of these processing steps takes place on threads managed by FIM CM. Any delays imposed by your object will add to the time needed for the server to issue a response to a client's request, and any blocking will block client HTTP requests from being processed, leading to slow-downs and even connection time-outs.

Helper Classes

In addition to ICardInitialization, the Microsoft.Clm namespace provides helper classes to aid with the card initialization process.

ICardContext

A read-only object of type ICardContext is passed to several ICardInitialization methods in order to provide them with the smart card's answer-to-reset (ATR) string and unique card ID.

SymmetricKey

Custom implementations of smart-card key encryption can derive from this abstract base class.

CustomCardInitializer Sample

Tailspin Toys has developed an assembly that implements ICardInitialization in order to provide their own custom smart-card initialization procedures. The source for this assembly, named CustomCardInitializer, can be found below.

C#  Copy Code
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Microsoft.Clm;
using Microsoft.Clm.Common;
using Microsoft.Clm.Common.Requests;
using Microsoft.Clm.BusinessLayer.SmartCard.BaseCsp;

namespace Tailspin.Clm.Smartcard
{
	public class CustomCardInitializer : ICardInitialization, IDisposable
	{
		private DefaultCardInitialization defaultCardInitialization;

		public CustomCardInitializer()
		{
			// Allocate default Smart Card initializer
			defaultCardInitialization = new DefaultCardInitialization();
			// TODO: Perform custom class initialization here
	}

		public void Initialize(string configData, string defaultAdminKeyData)
		{
			//Communicate that this function was called.
			System.Diagnostics.Trace.WriteLine(" CustomCardInitializer.Initialize was called ");
			// Perform default Smart Card initialization
			// defaultCardInitializer formats the card, sets a cardID if one is not present,, creates space for PIN History cache, 
			// and also performs operations defined in the BaseCSP spec to ready the card.

			defaultCardInitialization.Initialize(configData, defaultAdminKeyData);
			//TODO: Perform custom card initialization here
			// Eg: Creating additional files, loading applications etc..
			// This is also a good place to set the adminKey of the card. Note default initializer will diversify if specified in CLM configuration.
	}

		public Guid GenerateCardId(Guid requestUuid)
		{
			//Communicate that this function was called.
			System.Diagnostics.Trace.WriteLine(" CustomCardInitializer.GenerateCardId was called ");
			// TODO: The following method returns a sequential card ID from the default initializer.  Replace this call with your own custom ID generation/synchronization process.
			// NOTE: Card IDs need to be unique across all cards issued! Rely on an automatically unique ID type such as a GUID
			return defaultCardInitialization.GenerateCardId(requestUuid);
	}

		// GetCardChallengeResponse takes a parameter of type ICardContext.
		// This parameter contains information about the card being processed,
		// specifically, the card's unique ID and its answer-to-reset
		// (ATR) string.
		public byte[] GetCardChallengeResponse(ICardContext card, byte[] challenge, bool useDiversifiedKey)
		{
			//Communicate that this function was called.
			System.Diagnostics.Trace.WriteLine(" CustomCardInitializer.GetCardChallengeResponse was called ");

			// TODO: The following method returns the default challenge/response.  Replace this call with your own custom response based on your custom keys (see GetDiversifiedAdminKey), formatted as a byte array.
			// See BaseCSP specification to learn how to create Response for a given card Challenge.
			return defaultCardInitialization.GetCardChallengeResponse(card, challenge, useDiversifiedKey);
	}

		// GetDiversifiedAdminKey takes a parameter of type ICardContext.
		// This parameter contains information about the card being processed,
		// specifically, the card's unique ID and its answer-to-reset
		// (ATR) string.
		// It returns the diversified key as an object of type SymmetricKey. 
		// You can encrypt items using this object by calling its Encrypt() method.
		public SymmetricKey GetDiversifiedAdminKey(ICardContext card)
		{
			//Communicate that this function was called.
			System.Diagnostics.Trace.WriteLine(" CustomCardInitializer.GetDiversifiedAdminKey was called ");

		 // TODO: The following method returns the diversified admin key.  Replace this call with your own custom key diversification process.
			return defaultCardInitialization.GetDiversifiedAdminKey(card);
	}

		// This property returns the default administrative encryption key.
		// It returns the key as an object of type SymmetricKey. You can encrypt items using this object by calling its Encrypt() method.
		public SymmetricKey DefaultAdminKey
		{
			get
			{
				//Communicate that this function was called.
				System.Diagnostics.Trace.WriteLine(" CustomCardInitializer.DefaultAdminKey was called ");

				return defaultCardInitialization.DefaultAdminKey;
		}
	}
	
		#region IDisposable Members

		public void Dispose()
		{
			//Communicate that this function was called.
			System.Diagnostics.Trace.WriteLine(" CustomCardInitializer.Dispose was called ");

			defaultCardInitialization.Dispose();
	}

		#endregion
}
}

See Also