private static CspKeyContainerInfo GetCspKeyContainerInfo(
IntPtr hStore,
string thumbprint,
string symbolicName,
WindowsStoreType storeType)
{
CRYPT_KEY_PROV_INFO pInfo;
IntPtr pData = IntPtr.Zero;
IntPtr pCertContext = IntPtr.Zero;
try
{
// get the certificates.
pCertContext = FindCertificate(hStore, thumbprint);
if (pCertContext == IntPtr.Zero)
{
return null;
}
// get size of the private key provider info struct.
int dwInfoSize = 0;
int bResult = NativeMethods.CertGetCertificateContextProperty(
pCertContext,
CERT_KEY_PROV_INFO_PROP_ID,
pData,
ref dwInfoSize);
if (bResult == 0)
{
// property must not exist.
return null;
}
// get private key provider info.
pData = Marshal.AllocHGlobal(dwInfoSize);
bResult = NativeMethods.CertGetCertificateContextProperty(
pCertContext,
CERT_KEY_PROV_INFO_PROP_ID,
pData,
ref dwInfoSize);
if (bResult == 0)
{
int dwError = Marshal.GetLastWin32Error();
throw ServiceResultException.Create(
StatusCodes.BadUnexpectedError,
"Could not get the provider info for certificate. Error={0:X8}",
dwError);
}
try
{
pInfo = (CRYPT_KEY_PROV_INFO)Marshal.PtrToStructure(pData, typeof(CRYPT_KEY_PROV_INFO));
}
finally
{
Marshal.DestroyStructure(pData, typeof(CRYPT_KEY_PROV_INFO));
}
string name1 = Marshal.PtrToStringUni(pInfo.pwszProvName);
string name2 = Marshal.PtrToStringUni(pInfo.pwszContainerName);
Marshal.FreeHGlobal(pData);
pData = IntPtr.Zero;
// create the crypto service provide parameters.
CspParameters cps = new CspParameters(
pInfo.dwProvType,
name1,
name2);
cps.Flags = CspProviderFlags.UseExistingKey;
if (storeType != WindowsStoreType.CurrentUser)
{
cps.Flags |= CspProviderFlags.UseMachineKeyStore;
}
// get the container information.
CspKeyContainerInfo container = new CspKeyContainerInfo(cps);
// get the access rules on the file.
return container;
}
finally
{
if (pCertContext != IntPtr.Zero)
{
NativeMethods.CertFreeCertificateContext(pCertContext);
}
if (pData != IntPtr.Zero)
{
Marshal.FreeHGlobal(pData);
}
}
}