PageRenderTime 64ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/Interop.crypt32.cs

https://gitlab.com/0072016/0072016-corefx-
C# | 298 lines | 210 code | 68 blank | 20 comment | 6 complexity | 3e8c9c1afd8256b8ebb9c1dba476ad96 MD5 | raw file
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. // See the LICENSE file in the project root for more information.
  4. using System;
  5. using System.Text;
  6. using System.Diagnostics;
  7. using System.Runtime.InteropServices;
  8. using CryptographicException = System.Security.Cryptography.CryptographicException;
  9. using SafeBCryptKeyHandle = Microsoft.Win32.SafeHandles.SafeBCryptKeyHandle;
  10. using SafeX509ChainHandle = Microsoft.Win32.SafeHandles.SafeX509ChainHandle;
  11. using X509KeyUsageFlags = System.Security.Cryptography.X509Certificates.X509KeyUsageFlags;
  12. using SafeNCryptKeyHandle = Microsoft.Win32.SafeHandles.SafeNCryptKeyHandle;
  13. using Internal.Cryptography;
  14. using Internal.Cryptography.Pal.Native;
  15. internal static partial class Interop
  16. {
  17. public static partial class crypt32
  18. {
  19. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  20. public static unsafe extern bool CryptQueryObject(
  21. CertQueryObjectType dwObjectType,
  22. void* pvObject,
  23. ExpectedContentTypeFlags dwExpectedContentTypeFlags,
  24. ExpectedFormatTypeFlags dwExpectedFormatTypeFlags,
  25. int dwFlags, // reserved - always pass 0
  26. out CertEncodingType pdwMsgAndCertEncodingType,
  27. out ContentType pdwContentType,
  28. out FormatType pdwFormatType,
  29. out SafeCertStoreHandle phCertStore,
  30. out SafeCryptMsgHandle phMsg,
  31. out SafeCertContextHandle ppvContext
  32. );
  33. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  34. public static unsafe extern bool CryptQueryObject(
  35. CertQueryObjectType dwObjectType,
  36. void* pvObject,
  37. ExpectedContentTypeFlags dwExpectedContentTypeFlags,
  38. ExpectedFormatTypeFlags dwExpectedFormatTypeFlags,
  39. int dwFlags, // reserved - always pass 0
  40. IntPtr pdwMsgAndCertEncodingType,
  41. out ContentType pdwContentType,
  42. IntPtr pdwFormatType,
  43. IntPtr phCertStore,
  44. IntPtr phMsg,
  45. IntPtr ppvContext
  46. );
  47. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  48. public static unsafe extern bool CryptQueryObject(
  49. CertQueryObjectType dwObjectType,
  50. void* pvObject,
  51. ExpectedContentTypeFlags dwExpectedContentTypeFlags,
  52. ExpectedFormatTypeFlags dwExpectedFormatTypeFlags,
  53. int dwFlags, // reserved - always pass 0
  54. IntPtr pdwMsgAndCertEncodingType,
  55. out ContentType pdwContentType,
  56. IntPtr pdwFormatType,
  57. out SafeCertStoreHandle phCertStore,
  58. IntPtr phMsg,
  59. IntPtr ppvContext
  60. );
  61. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  62. public static extern bool CertGetCertificateContextProperty(SafeCertContextHandle pCertContext, CertContextPropId dwPropId, [Out] byte[] pvData, [In, Out] ref int pcbData);
  63. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  64. public static extern bool CertGetCertificateContextProperty(SafeCertContextHandle pCertContext, CertContextPropId dwPropId, [Out] out CRYPTOAPI_BLOB pvData, [In, Out] ref int pcbData);
  65. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "CertGetCertificateContextProperty")]
  66. public static extern bool CertGetCertificateContextPropertyString(SafeCertContextHandle pCertContext, CertContextPropId dwPropId, [Out] StringBuilder pvData, [In, Out] ref int pcbData);
  67. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  68. public static extern unsafe bool CertSetCertificateContextProperty(SafeCertContextHandle pCertContext, CertContextPropId dwPropId, CertSetPropertyFlags dwFlags, [In] CRYPTOAPI_BLOB* pvData);
  69. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  70. public static extern unsafe bool CertSetCertificateContextProperty(SafeCertContextHandle pCertContext, CertContextPropId dwPropId, CertSetPropertyFlags dwFlags, [In] CRYPT_KEY_PROV_INFO* pvData);
  71. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "CertGetNameStringW")]
  72. public static extern int CertGetNameString(SafeCertContextHandle pCertContext, CertNameType dwType, CertNameFlags dwFlags, [In] ref CertNameStringType pvTypePara, [Out] StringBuilder pszNameString, int cchNameString);
  73. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  74. public static extern SafeCertContextHandle CertDuplicateCertificateContext(IntPtr pCertContext);
  75. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "CertDuplicateCertificateContext")]
  76. public static extern SafeCertContextHandleWithKeyContainerDeletion CertDuplicateCertificateContextWithKeyContainerDeletion(IntPtr pCertContext);
  77. public static SafeCertStoreHandle CertOpenStore(CertStoreProvider lpszStoreProvider, CertEncodingType dwMsgAndCertEncodingType, IntPtr hCryptProv, CertStoreFlags dwFlags, string pvPara)
  78. {
  79. return CertOpenStore((IntPtr)lpszStoreProvider, dwMsgAndCertEncodingType, hCryptProv, dwFlags, pvPara);
  80. }
  81. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  82. private static extern SafeCertStoreHandle CertOpenStore(IntPtr lpszStoreProvider, CertEncodingType dwMsgAndCertEncodingType, IntPtr hCryptProv, CertStoreFlags dwFlags, [MarshalAs(UnmanagedType.LPWStr)] string pvPara);
  83. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  84. public static extern bool CertAddCertificateContextToStore(SafeCertStoreHandle hCertStore, SafeCertContextHandle pCertContext, CertStoreAddDisposition dwAddDisposition, IntPtr ppStoreContext);
  85. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  86. public static extern bool CertAddCertificateLinkToStore(SafeCertStoreHandle hCertStore, SafeCertContextHandle pCertContext, CertStoreAddDisposition dwAddDisposition, IntPtr ppStoreContext);
  87. /// <summary>
  88. /// A less error-prone wrapper for CertEnumCertificatesInStore().
  89. ///
  90. /// To begin the enumeration, set pCertContext to null. Each iteration replaces pCertContext with
  91. /// the next certificate in the iteration. The final call sets pCertContext to an invalid SafeCertStoreHandle
  92. /// and returns "false" to indicate the end of the store has been reached.
  93. /// </summary>
  94. public static bool CertEnumCertificatesInStore(SafeCertStoreHandle hCertStore, ref SafeCertContextHandle pCertContext)
  95. {
  96. unsafe
  97. {
  98. CERT_CONTEXT* pPrevCertContext = pCertContext == null ? null : pCertContext.Disconnect();
  99. pCertContext = CertEnumCertificatesInStore(hCertStore, pPrevCertContext);
  100. return !pCertContext.IsInvalid;
  101. }
  102. }
  103. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  104. private static extern unsafe SafeCertContextHandle CertEnumCertificatesInStore(SafeCertStoreHandle hCertStore, CERT_CONTEXT* pPrevCertContext);
  105. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  106. public static extern SafeCertStoreHandle PFXImportCertStore([In] ref CRYPTOAPI_BLOB pPFX, string szPassword, PfxCertStoreFlags dwFlags);
  107. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  108. public static extern bool CryptMsgGetParam(SafeCryptMsgHandle hCryptMsg, CryptMessageParameterType dwParamType, int dwIndex, [Out] byte[] pvData, [In, Out] ref int pcbData);
  109. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  110. public static extern bool CryptMsgGetParam(SafeCryptMsgHandle hCryptMsg, CryptMessageParameterType dwParamType, int dwIndex, out int pvData, [In, Out] ref int pcbData);
  111. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  112. public static extern bool CertSerializeCertificateStoreElement(SafeCertContextHandle pCertContext, int dwFlags, [Out] byte[] pbElement, [In, Out] ref int pcbElement);
  113. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  114. public static extern bool PFXExportCertStore(SafeCertStoreHandle hStore, [In, Out] ref CRYPTOAPI_BLOB pPFX, string szPassword, PFXExportFlags dwFlags);
  115. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "CertNameToStrW")]
  116. public static extern int CertNameToStr(CertEncodingType dwCertEncodingType, [In] ref CRYPTOAPI_BLOB pName, CertNameStrTypeAndFlags dwStrType, StringBuilder psz, int csz);
  117. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "CertStrToNameW")]
  118. public static extern bool CertStrToName(CertEncodingType dwCertEncodingType, string pszX500, CertNameStrTypeAndFlags dwStrType, IntPtr pvReserved, [Out] byte[] pbEncoded, [In, Out] ref int pcbEncoded, IntPtr ppszError);
  119. public static bool CryptFormatObject(CertEncodingType dwCertEncodingType, FormatObjectType dwFormatType, FormatObjectStringType dwFormatStrType, IntPtr pFormatStruct, FormatObjectStructType lpszStructType, byte[] pbEncoded, int cbEncoded, StringBuilder pbFormat, ref int pcbFormat)
  120. {
  121. return CryptFormatObject(dwCertEncodingType, dwFormatType, dwFormatStrType, pFormatStruct, (IntPtr)lpszStructType, pbEncoded, cbEncoded, pbFormat, ref pcbFormat);
  122. }
  123. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  124. private static extern bool CryptFormatObject(CertEncodingType dwCertEncodingType, FormatObjectType dwFormatType, FormatObjectStringType dwFormatStrType, IntPtr pFormatStruct, IntPtr lpszStructType, [In] byte[] pbEncoded, int cbEncoded, [Out] StringBuilder pbFormat, [In, Out] ref int pcbFormat);
  125. public static bool CryptDecodeObject(CertEncodingType dwCertEncodingType, CryptDecodeObjectStructType lpszStructType, byte[] pbEncoded, int cbEncoded, CryptDecodeObjectFlags dwFlags, byte[] pvStructInfo, ref int pcbStructInfo)
  126. {
  127. return CryptDecodeObject(dwCertEncodingType, (IntPtr)lpszStructType, pbEncoded, cbEncoded, dwFlags, pvStructInfo, ref pcbStructInfo);
  128. }
  129. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  130. private static extern bool CryptDecodeObject(CertEncodingType dwCertEncodingType, IntPtr lpszStructType, [In] byte[] pbEncoded, int cbEncoded, CryptDecodeObjectFlags dwFlags, [Out] byte[] pvStructInfo, [In, Out] ref int pcbStructInfo);
  131. public static unsafe bool CryptDecodeObjectPointer(CertEncodingType dwCertEncodingType, CryptDecodeObjectStructType lpszStructType, byte[] pbEncoded, int cbEncoded, CryptDecodeObjectFlags dwFlags, void* pvStructInfo, ref int pcbStructInfo)
  132. {
  133. return CryptDecodeObjectPointer(dwCertEncodingType, (IntPtr)lpszStructType, pbEncoded, cbEncoded, dwFlags, pvStructInfo, ref pcbStructInfo);
  134. }
  135. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "CryptDecodeObject")]
  136. private static extern unsafe bool CryptDecodeObjectPointer(CertEncodingType dwCertEncodingType, IntPtr lpszStructType, [In] byte[] pbEncoded, int cbEncoded, CryptDecodeObjectFlags dwFlags, [Out] void* pvStructInfo, [In, Out] ref int pcbStructInfo);
  137. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "CryptDecodeObject")]
  138. public static extern unsafe bool CryptDecodeObjectPointer(CertEncodingType dwCertEncodingType, [MarshalAs(UnmanagedType.LPStr)] string lpszStructType, [In] byte[] pbEncoded, int cbEncoded, CryptDecodeObjectFlags dwFlags, [Out] void* pvStructInfo, [In, Out] ref int pcbStructInfo);
  139. public static unsafe bool CryptEncodeObject(CertEncodingType dwCertEncodingType, CryptDecodeObjectStructType lpszStructType, void* pvStructInfo, byte[] pbEncoded, ref int pcbEncoded)
  140. {
  141. return CryptEncodeObject(dwCertEncodingType, (IntPtr)lpszStructType, pvStructInfo, pbEncoded, ref pcbEncoded);
  142. }
  143. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  144. private static extern unsafe bool CryptEncodeObject(CertEncodingType dwCertEncodingType, IntPtr lpszStructType, void* pvStructInfo, [Out] byte[] pbEncoded, [In, Out] ref int pcbEncoded);
  145. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  146. public static extern unsafe bool CryptEncodeObject(CertEncodingType dwCertEncodingType, [MarshalAs(UnmanagedType.LPStr)] string lpszStructType, void* pvStructInfo, [Out] byte[] pbEncoded, [In, Out] ref int pcbEncoded);
  147. public static unsafe byte[] EncodeObject(CryptDecodeObjectStructType lpszStructType, void* decoded)
  148. {
  149. int cb = 0;
  150. if (!Interop.crypt32.CryptEncodeObject(CertEncodingType.All, lpszStructType, decoded, null, ref cb))
  151. throw Marshal.GetLastWin32Error().ToCryptographicException();
  152. byte[] encoded = new byte[cb];
  153. if (!Interop.crypt32.CryptEncodeObject(CertEncodingType.All, lpszStructType, decoded, encoded, ref cb))
  154. throw Marshal.GetLastWin32Error().ToCryptographicException();
  155. return encoded;
  156. }
  157. public static unsafe byte[] EncodeObject(string lpszStructType, void* decoded)
  158. {
  159. int cb = 0;
  160. if (!Interop.crypt32.CryptEncodeObject(CertEncodingType.All, lpszStructType, decoded, null, ref cb))
  161. throw Marshal.GetLastWin32Error().ToCryptographicException();
  162. byte[] encoded = new byte[cb];
  163. if (!Interop.crypt32.CryptEncodeObject(CertEncodingType.All, lpszStructType, decoded, encoded, ref cb))
  164. throw Marshal.GetLastWin32Error().ToCryptographicException();
  165. return encoded;
  166. }
  167. public static unsafe bool CertGetCertificateChain(ChainEngine hChainEngine, SafeCertContextHandle pCertContext, FILETIME* pTime, SafeCertStoreHandle hStore, [In] ref CERT_CHAIN_PARA pChainPara, CertChainFlags dwFlags, IntPtr pvReserved, out SafeX509ChainHandle ppChainContext)
  168. {
  169. return CertGetCertificateChain((IntPtr)hChainEngine, pCertContext, pTime, hStore, ref pChainPara, dwFlags, pvReserved, out ppChainContext);
  170. }
  171. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  172. private static extern unsafe bool CertGetCertificateChain(IntPtr hChainEngine, SafeCertContextHandle pCertContext, FILETIME* pTime, SafeCertStoreHandle hStore, [In] ref CERT_CHAIN_PARA pChainPara, CertChainFlags dwFlags, IntPtr pvReserved, out SafeX509ChainHandle ppChainContext);
  173. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  174. public static extern bool CryptHashPublicKeyInfo(IntPtr hCryptProv, int algId, int dwFlags, CertEncodingType dwCertEncodingType, [In] ref CERT_PUBLIC_KEY_INFO pInfo, [Out] byte[] pbComputedHash, [In, Out] ref int pcbComputedHash);
  175. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "CertGetNameStringW")]
  176. public static extern int CertGetNameString(SafeCertContextHandle pCertContext, CertNameType dwType, CertNameFlags dwFlags, [In] ref CertNameStrTypeAndFlags pvPara, [Out] StringBuilder pszNameString, int cchNameString);
  177. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  178. public static extern bool CertSaveStore(SafeCertStoreHandle hCertStore, CertEncodingType dwMsgAndCertEncodingType, CertStoreSaveAs dwSaveAs, CertStoreSaveTo dwSaveTo, ref CRYPTOAPI_BLOB pvSaveToPara, int dwFlags);
  179. /// <summary>
  180. /// A less error-prone wrapper for CertEnumCertificatesInStore().
  181. ///
  182. /// To begin the enumeration, set pCertContext to null. Each iteration replaces pCertContext with
  183. /// the next certificate in the iteration. The final call sets pCertContext to an invalid SafeCertStoreHandle
  184. /// and returns "false" to indicate the end of the store has been reached.
  185. /// </summary>
  186. public static unsafe bool CertFindCertificateInStore(SafeCertStoreHandle hCertStore, CertFindType dwFindType, void* pvFindPara, ref SafeCertContextHandle pCertContext)
  187. {
  188. CERT_CONTEXT* pPrevCertContext = pCertContext == null ? null : pCertContext.Disconnect();
  189. pCertContext = CertFindCertificateInStore(hCertStore, CertEncodingType.All, CertFindFlags.None, dwFindType, pvFindPara, pPrevCertContext);
  190. return !pCertContext.IsInvalid;
  191. }
  192. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  193. private static unsafe extern SafeCertContextHandle CertFindCertificateInStore(SafeCertStoreHandle hCertStore, CertEncodingType dwCertEncodingType, CertFindFlags dwFindFlags, CertFindType dwFindType, void* pvFindPara, CERT_CONTEXT* pPrevCertContext);
  194. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  195. public static unsafe extern int CertVerifyTimeValidity([In] ref FILETIME pTimeToVerify, [In] CERT_INFO* pCertInfo);
  196. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  197. public static unsafe extern CERT_EXTENSION* CertFindExtension([MarshalAs(UnmanagedType.LPStr)] string pszObjId, int cExtensions, CERT_EXTENSION* rgExtensions);
  198. // Note: It's somewhat unusual to use an API enum as a parameter type to a P/Invoke but in this case, X509KeyUsageFlags was intentionally designed as bit-wise
  199. // identical to the wincrypt CERT_*_USAGE values.
  200. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  201. public static unsafe extern bool CertGetIntendedKeyUsage(CertEncodingType dwCertEncodingType, CERT_INFO* pCertInfo, out X509KeyUsageFlags pbKeyUsage, int cbKeyUsage);
  202. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  203. public static unsafe extern bool CertGetValidUsages(int cCerts, [In] ref SafeCertContextHandle rghCerts, out int cNumOIDs, [Out] void* rghOIDs, [In, Out] ref int pcbOIDs);
  204. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  205. public static extern bool CertControlStore(SafeCertStoreHandle hCertStore, CertControlStoreFlags dwFlags, CertControlStoreType dwControlType, IntPtr pvCtrlPara);
  206. // Note: CertDeleteCertificateFromStore always calls CertFreeCertificateContext on pCertContext, even if an error is encountered.
  207. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  208. public static extern unsafe bool CertDeleteCertificateFromStore(CERT_CONTEXT* pCertContext);
  209. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  210. public static extern void CertFreeCertificateChain(IntPtr pChainContext);
  211. public static bool CertVerifyCertificateChainPolicy(ChainPolicy pszPolicyOID, SafeX509ChainHandle pChainContext, ref CERT_CHAIN_POLICY_PARA pPolicyPara, ref CERT_CHAIN_POLICY_STATUS pPolicyStatus)
  212. {
  213. return CertVerifyCertificateChainPolicy((IntPtr)pszPolicyOID, pChainContext, ref pPolicyPara, ref pPolicyStatus);
  214. }
  215. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  216. private static extern bool CertVerifyCertificateChainPolicy(IntPtr pszPolicyOID, SafeX509ChainHandle pChainContext, [In] ref CERT_CHAIN_POLICY_PARA pPolicyPara, [In, Out] ref CERT_CHAIN_POLICY_STATUS pPolicyStatus);
  217. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  218. public static extern bool CertFreeCertificateContext(IntPtr pCertContext);
  219. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  220. public static extern bool CertCloseStore(IntPtr hCertStore, int dwFlags);
  221. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  222. public static extern bool CryptMsgClose(IntPtr hCryptMsg);
  223. #if !NETNATIVE
  224. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  225. public static extern unsafe bool CryptImportPublicKeyInfoEx2(CertEncodingType dwCertEncodingType, CERT_PUBLIC_KEY_INFO* pInfo, int dwFlags, void* pvAuxInfo, out SafeBCryptKeyHandle phKey);
  226. #endif
  227. [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
  228. public static extern bool CryptAcquireCertificatePrivateKey(SafeCertContextHandle pCert, CryptAcquireFlags dwFlags, IntPtr pvParameters, out SafeNCryptKeyHandle phCryptProvOrNCryptKey, out int pdwKeySpec, out bool pfCallerFreeProvOrNCryptKey);
  229. }
  230. }