private static FileInfo GetKeyFileInfo(string uniqueId, WindowsStoreType storeType, string userSid)
{
StringBuilder rootDir = new StringBuilder();
switch (storeType)
{
case WindowsStoreType.LocalMachine:
case WindowsStoreType.Service:
{
rootDir.Append(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData));
rootDir.Append("\\Microsoft\\Crypto\\RSA\\MachineKeys");
break;
}
case WindowsStoreType.CurrentUser:
{
rootDir.Append(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
rootDir.Append("\\Microsoft\\Crypto\\RSA\\");
break;
}
case WindowsStoreType.User:
{
// assume other users are in the same location as the AllUser folder.
string startDir = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
DirectoryInfo info = new DirectoryInfo(startDir);
// translate the sid to a user name.
SecurityIdentifier sid = new SecurityIdentifier(userSid);
string userName = sid.Translate(typeof(NTAccount)).ToString();
int index = userName.LastIndexOf('\\');
if (index != -1)
{
userName = userName.Substring(index+1);
}
// construct a new dir using the user name.
rootDir.Append(info.Parent.Parent.FullName);
rootDir.AppendFormat("\\{0}\\{1}\\Microsoft\\Crypto\\RSA\\", userName, info.Parent.Name);
break;
}
}
// open directory.
DirectoryInfo directory = new DirectoryInfo(rootDir.ToString());
if (!directory.Exists)
{
throw new InvalidOperationException(
Utils.Format("Could not find directory containing key file.\r\nKey={0}, Directory={1}",
uniqueId,
directory.FullName));
}
// file the key file.
IList<FileInfo> files = directory.GetFiles(uniqueId, SearchOption.AllDirectories);
if (files.Count == 0)
{
throw new InvalidOperationException(
Utils.Format("Could not find private key file.\r\nKey={0}, Directory={1}",
uniqueId,
directory.FullName));
}
if (files.Count > 1)
{
throw new InvalidOperationException(
Utils.Format("Multiple key files with the same name exist.\r\nKey={0}, Directory={1}",
uniqueId,
directory.FullName));
}
// return the complete path.
return files[0];
}