Example #1
0
 /// <summary>
 /// A less error-prone wrapper for CertEnumCertificatesInStore().
 /// 
 /// To begin the enumeration, set pCertContext to null. Each iteration replaces pCertContext with
 /// the next certificate in the iteration. The final call sets pCertContext to an invalid SafeCertStoreHandle 
 /// and returns "false" to indicate the end of the store has been reached.
 /// </summary>
 public static bool CertEnumCertificatesInStore(SafeCertStoreHandle hCertStore, ref SafeCertContextHandle pCertContext)
 {
     unsafe
     {
         CERT_CONTEXT* pPrevCertContext = pCertContext == null ? null : pCertContext.Disconnect();
         pCertContext = CertEnumCertificatesInStore(hCertStore, pPrevCertContext);
         return !pCertContext.IsInvalid;
     }
 }
Example #2
0
 public static unsafe extern bool CryptQueryObject(
     CertQueryObjectType dwObjectType,
     void* pvObject,
     ExpectedContentTypeFlags dwExpectedContentTypeFlags,
     ExpectedFormatTypeFlags dwExpectedFormatTypeFlags,
     int dwFlags, // reserved - always pass 0
     IntPtr pdwMsgAndCertEncodingType,
     out ContentType pdwContentType,
     IntPtr pdwFormatType,
     out SafeCertStoreHandle phCertStore,
     IntPtr phMsg,
     IntPtr ppvContext
     );
        private unsafe static byte[] ExportCertificatesToBlob(SafeCertStoreHandle safeCertStoreHandle, X509ContentType contentType, string password) {
            SafeCertContextHandle safeCertContextHandle = SafeCertContextHandle.InvalidHandle;
            uint dwSaveAs = CAPI.CERT_STORE_SAVE_AS_PKCS7;
            byte[] pbBlob = null;
            CAPI.CRYPTOAPI_BLOB DataBlob = new CAPI.CRYPTOAPI_BLOB();
            SafeLocalAllocHandle pbEncoded = SafeLocalAllocHandle.InvalidHandle;

            switch(contentType) {
            case X509ContentType.Cert:
                safeCertContextHandle = CAPI.CertEnumCertificatesInStore(safeCertStoreHandle, safeCertContextHandle);
                if (safeCertContextHandle != null && !safeCertContextHandle.IsInvalid) {
                    CAPI.CERT_CONTEXT pCertContext = *((CAPI.CERT_CONTEXT*) safeCertContextHandle.DangerousGetHandle());
                    pbBlob = new byte[pCertContext.cbCertEncoded];
                    Marshal.Copy(pCertContext.pbCertEncoded, pbBlob, 0, pbBlob.Length);
                }
                break;

            case X509ContentType.SerializedCert:
                safeCertContextHandle = CAPI.CertEnumCertificatesInStore(safeCertStoreHandle, safeCertContextHandle);
                uint cbEncoded = 0;
                if (safeCertContextHandle != null && !safeCertContextHandle.IsInvalid) {
                    if (!CAPI.CertSerializeCertificateStoreElement(safeCertContextHandle, 
                                                                   0, 
                                                                   pbEncoded, 
                                                                   new IntPtr(&cbEncoded))) 
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    pbEncoded = CAPI.LocalAlloc(CAPI.LMEM_FIXED, new IntPtr(cbEncoded));
                    if (!CAPI.CertSerializeCertificateStoreElement(safeCertContextHandle, 
                                                                   0, 
                                                                   pbEncoded, 
                                                                   new IntPtr(&cbEncoded)))
                        throw new CryptographicException(Marshal.GetLastWin32Error());

                    pbBlob = new byte[cbEncoded];
                    Marshal.Copy(pbEncoded.DangerousGetHandle(), pbBlob, 0, pbBlob.Length);
                }
                break;

            case X509ContentType.Pkcs12:
                if (!CAPI.PFXExportCertStore(safeCertStoreHandle, 
                                             new IntPtr(&DataBlob), 
                                             password, 
                                             CAPI.EXPORT_PRIVATE_KEYS | CAPI.REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY))
                    throw new CryptographicException(Marshal.GetLastWin32Error());

                pbEncoded = CAPI.LocalAlloc(CAPI.LMEM_FIXED, new IntPtr(DataBlob.cbData));
                DataBlob.pbData = pbEncoded.DangerousGetHandle();
                if (!CAPI.PFXExportCertStore(safeCertStoreHandle, 
                                             new IntPtr(&DataBlob),
                                             password, 
                                             CAPI.EXPORT_PRIVATE_KEYS | CAPI.REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY))
                    throw new CryptographicException(Marshal.GetLastWin32Error());

                pbBlob = new byte[DataBlob.cbData];
                Marshal.Copy(DataBlob.pbData, pbBlob, 0, pbBlob.Length);
                break;

            case X509ContentType.SerializedStore:
                // falling through
            case X509ContentType.Pkcs7:
                if (contentType == X509ContentType.SerializedStore)
                    dwSaveAs = CAPI.CERT_STORE_SAVE_AS_STORE;

                // determine the required length
                if (!CAPI.CertSaveStore(safeCertStoreHandle, 
                                        CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, 
                                        dwSaveAs, 
                                        CAPI.CERT_STORE_SAVE_TO_MEMORY, 
                                        new IntPtr(&DataBlob), 
                                        0)) 
                    throw new CryptographicException(Marshal.GetLastWin32Error());

                pbEncoded = CAPI.LocalAlloc(CAPI.LMEM_FIXED, new IntPtr(DataBlob.cbData));
                DataBlob.pbData = pbEncoded.DangerousGetHandle();
                // now save the store to a memory blob
                if (!CAPI.CertSaveStore(safeCertStoreHandle, 
                                        CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, 
                                        dwSaveAs, 
                                        CAPI.CERT_STORE_SAVE_TO_MEMORY, 
                                        new IntPtr(&DataBlob), 
                                        0)) 
                    throw new CryptographicException(Marshal.GetLastWin32Error());

                pbBlob = new byte[DataBlob.cbData];
                Marshal.Copy(DataBlob.pbData, pbBlob, 0, pbBlob.Length);
                break;

            default:
                throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidContentType));
            }

            pbEncoded.Dispose();
            safeCertContextHandle.Dispose();

            return pbBlob;
        }
        private static void FindByCert(SafeCertStoreHandle safeSourceStoreHandle, 
                                        uint dwFindType, 
                                        IntPtr pvFindPara, 
                                        bool validOnly, 
                                        FindProcDelegate pfnCertCallback1, 
                                        FindProcDelegate pfnCertCallback2, 
                                        object pvCallbackData1, 
                                        object pvCallbackData2, 
                                        SafeCertStoreHandle safeTargetStoreHandle) {

            int hr = CAPI.S_OK;

            SafeCertContextHandle pEnumContext = SafeCertContextHandle.InvalidHandle;
            pEnumContext = CAPI.CertFindCertificateInStore(safeSourceStoreHandle, 
                                                           CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
                                                           0, 
                                                           dwFindType,
                                                           pvFindPara,
                                                           pEnumContext);

            while (pEnumContext != null && !pEnumContext.IsInvalid) {
                if (pfnCertCallback1 != null) {
                    hr = pfnCertCallback1(pEnumContext, pvCallbackData1);
                    if (hr == CAPI.S_FALSE) {
                        if (pfnCertCallback2 != null) 
                            hr = pfnCertCallback2(pEnumContext, pvCallbackData2);

                        if (hr == CAPI.S_FALSE) // skip this certificate
                            goto skip;
                    }

                    if (hr != CAPI.S_OK)
                        break;
                }

                if (validOnly) {
                    hr = X509Utils.VerifyCertificate(pEnumContext, 
                                           null,
                                           null,
                                           X509RevocationMode.NoCheck,
                                           X509RevocationFlag.ExcludeRoot,
                                           DateTime.Now,
                                           new TimeSpan(0, 0, 0), // default
                                           null,
                                           new IntPtr(CAPI.CERT_CHAIN_POLICY_BASE), 
                                           IntPtr.Zero);
                    if (hr == CAPI.S_FALSE) // skip this certificate
                        goto skip;

                    if (hr != CAPI.S_OK)
                        break;
                }

                //
                // We use CertAddCertificateLinkToStore to keep a link to the original store, so any property changes get
                // applied to the original store. This has a limit of 99 links per cert context however.
                //

                if (!CAPI.CertAddCertificateLinkToStore(safeTargetStoreHandle, 
                                                        pEnumContext, 
                                                        CAPI.CERT_STORE_ADD_ALWAYS, 
                                                        SafeCertContextHandle.InvalidHandle)) {
                    hr = Marshal.GetHRForLastWin32Error();
                    break;
                }

skip:
                // CertFindCertificateInStore always releases the context regardless of success 
                // or failure so we don't need to manually release it
                GC.SuppressFinalize(pEnumContext);

                pEnumContext = CAPI.CertFindCertificateInStore(safeSourceStoreHandle, 
                                                               CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
                                                               0, 
                                                               dwFindType, 
                                                               pvFindPara,
                                                               pEnumContext);
            }

            if (pEnumContext != null && !pEnumContext.IsInvalid)
                pEnumContext.Dispose();

            if (hr != CAPI.S_FALSE && hr != CAPI.S_OK)
                throw new CryptographicException(hr);
        }
Example #5
0
        private static ICertificatePal FromBlobOrFile(byte[] rawData, string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
        {
            Debug.Assert(rawData != null || fileName != null);
            Debug.Assert(password != null);

            bool loadFromFile = (fileName != null);

            PfxCertStoreFlags pfxCertStoreFlags = MapKeyStorageFlags(keyStorageFlags);
            bool persistKeySet = (0 != (keyStorageFlags & X509KeyStorageFlags.PersistKeySet));

            CertEncodingType      msgAndCertEncodingType;
            ContentType           contentType;
            FormatType            formatType;
            SafeCertStoreHandle   hCertStore   = null;
            SafeCryptMsgHandle    hCryptMsg    = null;
            SafeCertContextHandle pCertContext = null;

            try
            {
                unsafe
                {
                    fixed(byte *pRawData = rawData)
                    {
                        fixed(char *pFileName = fileName)
                        {
                            CRYPTOAPI_BLOB certBlob = new CRYPTOAPI_BLOB(loadFromFile ? 0 : rawData.Length, pRawData);

                            CertQueryObjectType objectType = loadFromFile ? CertQueryObjectType.CERT_QUERY_OBJECT_FILE : CertQueryObjectType.CERT_QUERY_OBJECT_BLOB;
                            void *pvObject = loadFromFile ? (void *)pFileName : (void *)&certBlob;

                            bool success = Interop.crypt32.CryptQueryObject(
                                objectType,
                                pvObject,
                                X509ExpectedContentTypeFlags,
                                X509ExpectedFormatTypeFlags,
                                0,
                                out msgAndCertEncodingType,
                                out contentType,
                                out formatType,
                                out hCertStore,
                                out hCryptMsg,
                                out pCertContext
                                );

                            if (!success)
                            {
                                int hr = Marshal.GetHRForLastWin32Error();
                                throw hr.ToCryptographicException();
                            }
                        }
                    }

                    if (contentType == ContentType.CERT_QUERY_CONTENT_PKCS7_SIGNED || contentType == ContentType.CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED)
                    {
                        pCertContext = GetSignerInPKCS7Store(hCertStore, hCryptMsg);
                    }
                    else if (contentType == ContentType.CERT_QUERY_CONTENT_PFX)
                    {
                        if (loadFromFile)
                        {
                            rawData = File.ReadAllBytes(fileName);
                        }
                        pCertContext = FilterPFXStore(rawData, password, pfxCertStoreFlags);
                    }

                    CertificatePal pal = new CertificatePal(pCertContext, deleteKeyContainer: !persistKeySet);

                    pCertContext = null;
                    return(pal);
                }
            }
            finally
            {
                if (hCertStore != null)
                {
                    hCertStore.Dispose();
                }
                if (hCryptMsg != null)
                {
                    hCryptMsg.Dispose();
                }
                if (pCertContext != null)
                {
                    pCertContext.Dispose();
                }
            }
        }
Example #6
0
 public void Dispose()
 {
     SafeCertStoreHandle certStore = _certStore;
     _certStore = null;
     if (certStore != null)
         certStore.Dispose();
 }
Example #7
0
 public static extern bool CertAddCertificateContextToStore(SafeCertStoreHandle hCertStore, SafeCertContextHandle pCertContext, CertStoreAddDisposition dwAddDisposition, IntPtr ppStoreContext);
 internal static extern void _AddCertificateToStore(SafeCertStoreHandle safeCertStoreHandle, SafeCertContextHandle safeCertContext);
        static SafeCertStoreHandle ExportToMemoryStore(X509Certificate2Collection collection, IntPtr pCertContext)
        {
            CAPI.CERT_CONTEXT certContext = (CAPI.CERT_CONTEXT)Marshal.PtrToStructure(pCertContext, typeof(CAPI.CERT_CONTEXT));

            // No extra store nor intermediate certificates
            if ((collection == null || collection.Count <= 0) && certContext.hCertStore == IntPtr.Zero)
            {
                return(SafeCertStoreHandle.InvalidHandle);
            }

            // we always want to use CERT_STORE_ENUM_ARCHIVED_FLAG since we want to preserve the collection in this operation.
            // By default, Archived certificates will not be included.
            SafeCertStoreHandle certStoreHandle = CAPI.CertOpenStore(
                new IntPtr(CAPI.CERT_STORE_PROV_MEMORY),
                CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
                IntPtr.Zero,
                CAPI.CERT_STORE_ENUM_ARCHIVED_FLAG | CAPI.CERT_STORE_CREATE_NEW_FLAG,
                null);

            if (certStoreHandle == null || certStoreHandle.IsInvalid)
            {
                int error = Marshal.GetLastWin32Error();
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(error));
            }

            //
            // We use CertAddCertificateLinkToStore to keep a link to the original store, so any property changes get
            // applied to the original store. This has a limit of 99 links per cert context however.
            //

            // Add extra store
            if (collection != null && collection.Count > 0)
            {
                foreach (X509Certificate2 x509 in collection)
                {
                    if (!CAPI.CertAddCertificateLinkToStore(certStoreHandle,
                                                            x509.Handle,
                                                            CAPI.CERT_STORE_ADD_ALWAYS,
                                                            SafeCertContextHandle.InvalidHandle))
                    {
                        int error = Marshal.GetLastWin32Error();
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(error));
                    }
                }
            }

            // Add intermediates
            // The hCertStore needs to be acquired from an X509Certificate2 object
            // constructed using a fresh cert context handle. If we simply refer to the hCertStore
            // property of the certContext local variable directly, there is a risk that we are accessing
            // a closed store. This is because if the X509Certificate2(rawdata) constructor closes the store handle (hCertStore).
            // There is no way to know which constructor was used at this point.
            //
            using (SafeCertContextHandle safeCertContext
                       = CAPI.CertCreateCertificateContext(certContext.dwCertEncodingType,
                                                           certContext.pbCertEncoded,
                                                           certContext.cbCertEncoded))
            {
                //
                // Create an X509Certificate2 using the new cert context that dup's the provided certificate.
                //
                X509Certificate2 intermediatesCert = new X509Certificate2(safeCertContext.DangerousGetHandle());

                //
                // Dereference the handle to this intermediate cert and use it to access the handle
                // of this certificate's cert store. Then, call CAPI.CertAddCertificateLinkToStore
                // on each cert in this store by wrapping this cert store handle with an X509Store
                // object.
                //
                CAPI.CERT_CONTEXT intermediatesCertContext = (CAPI.CERT_CONTEXT)Marshal.PtrToStructure(intermediatesCert.Handle, typeof(CAPI.CERT_CONTEXT));
                if (intermediatesCertContext.hCertStore != IntPtr.Zero)
                {
                    X509Certificate2Collection intermediates = null;
                    X509Store store = new X509Store(intermediatesCertContext.hCertStore);

                    try
                    {
                        intermediates = store.Certificates;
                        foreach (X509Certificate2 x509 in intermediates)
                        {
                            if (!CAPI.CertAddCertificateLinkToStore(certStoreHandle,
                                                                    x509.Handle,
                                                                    CAPI.CERT_STORE_ADD_ALWAYS,
                                                                    SafeCertContextHandle.InvalidHandle))
                            {
                                int error = Marshal.GetLastWin32Error();
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(error));
                            }
                        }
                    }
                    finally
                    {
                        SecurityUtils.ResetAllCertificates(intermediates);
                        store.Close();
                    }
                }
            }

            return(certStoreHandle);
        }
Example #10
0
 /// <summary>
 /// A less error-prone wrapper for CertEnumCertificatesInStore().
 /// 
 /// To begin the enumeration, set pCertContext to null. Each iteration replaces pCertContext with
 /// the next certificate in the iteration. The final call sets pCertContext to an invalid SafeCertStoreHandle 
 /// and returns "false" to indicate the the end of the store has been reached.
 /// </summary>
 public static unsafe bool CertFindCertificateInStore(SafeCertStoreHandle hCertStore, CertFindType dwFindType, void* pvFindPara, ref SafeCertContextHandle pCertContext)
 {
     CERT_CONTEXT* pPrevCertContext = pCertContext == null ? null : pCertContext.Disconnect();
     pCertContext = CertFindCertificateInStore(hCertStore, CertEncodingType.All, CertFindFlags.None, dwFindType, pvFindPara, pPrevCertContext);
     return !pCertContext.IsInvalid;
 }
 internal static extern IntPtr CertEnumCertificatesInStore(SafeCertStoreHandle hCertStore, IntPtr pPrevCertContext);
        static unsafe void BuildChain(IntPtr hChainEngine,
                                      IntPtr pCertContext,
                                      X509Certificate2Collection extraStore,
                                      OidCollection applicationPolicy,
                                      OidCollection certificatePolicy,
                                      X509RevocationMode revocationMode,
                                      X509RevocationFlag revocationFlag,
                                      DateTime verificationTime,
                                      TimeSpan timeout,
                                      out SafeCertChainHandle ppChainContext)
        {
            SafeCertStoreHandle hCertStore = ExportToMemoryStore(extraStore, pCertContext);

            CAPI.CERT_CHAIN_PARA ChainPara = new CAPI.CERT_CHAIN_PARA();
            ChainPara.cbSize = (uint)Marshal.SizeOf(typeof(CAPI.CERT_CHAIN_PARA));

            // Application policy
            SafeHGlobalHandle applicationPolicyHandle = SafeHGlobalHandle.InvalidHandle;
            SafeHGlobalHandle certificatePolicyHandle = SafeHGlobalHandle.InvalidHandle;

            try
            {
                if (applicationPolicy != null && applicationPolicy.Count > 0)
                {
                    ChainPara.RequestedUsage.dwType = CAPI.USAGE_MATCH_TYPE_AND;
                    ChainPara.RequestedUsage.Usage.cUsageIdentifier = (uint)applicationPolicy.Count;
                    applicationPolicyHandle = CopyOidsToUnmanagedMemory(applicationPolicy);
                    ChainPara.RequestedUsage.Usage.rgpszUsageIdentifier = applicationPolicyHandle.DangerousGetHandle();
                }

                // Certificate policy
                if (certificatePolicy != null && certificatePolicy.Count > 0)
                {
                    ChainPara.RequestedIssuancePolicy.dwType = CAPI.USAGE_MATCH_TYPE_AND;
                    ChainPara.RequestedIssuancePolicy.Usage.cUsageIdentifier = (uint)certificatePolicy.Count;
                    certificatePolicyHandle = CopyOidsToUnmanagedMemory(certificatePolicy);
                    ChainPara.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = certificatePolicyHandle.DangerousGetHandle();
                }

                ChainPara.dwUrlRetrievalTimeout = (uint)timeout.Milliseconds;

                FILETIME ft = new FILETIME();
                *((long *)&ft) = verificationTime.ToFileTime();

                uint flags = MapRevocationFlags(revocationMode, revocationFlag);

                // Build the chain.
                if (!CAPI.CertGetCertificateChain(hChainEngine,
                                                  pCertContext,
                                                  ref ft,
                                                  hCertStore,
                                                  ref ChainPara,
                                                  flags,
                                                  IntPtr.Zero,
                                                  out ppChainContext))
                {
                    int error = Marshal.GetLastWin32Error();
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(error));
                }
            }
            finally
            {
                if (applicationPolicyHandle != null)
                {
                    applicationPolicyHandle.Dispose();
                }
                if (certificatePolicyHandle != null)
                {
                    certificatePolicyHandle.Dispose();
                }
                hCertStore.Close();
            }
        }
Example #13
0
 /// <summary>
 /// A less error-prone wrapper for CertEnumCertificatesInStore().
 ///
 /// To begin the enumeration, set pCertContext to null. Each iteration replaces pCertContext with
 /// the next certificate in the iteration. The final call sets pCertContext to an invalid SafeCertStoreHandle
 /// and returns "false" to indicate the end of the store has been reached.
 /// </summary>
 public static unsafe bool CertFindCertificateInStore(SafeCertStoreHandle hCertStore, Interop.Crypt32.CertFindType dwFindType, void *pvFindPara, [NotNull] ref SafeCertContextHandle?pCertContext)
 {
     Interop.Crypt32.CERT_CONTEXT *pPrevCertContext = pCertContext == null ? null : pCertContext.Disconnect();
     pCertContext = Interop.Crypt32.CertFindCertificateInStore(hCertStore, Interop.Crypt32.CertEncodingType.All, Interop.Crypt32.CertFindFlags.None, dwFindType, pvFindPara, pPrevCertContext);
     return(!pCertContext.IsInvalid);
 }
        public void Open(OpenFlags openFlags)
        {
            DiagnosticUtility.DebugAssert(this.certStoreHandle.IsInvalid, "");

            uint dwOpenFlags = MapX509StoreFlags(this.storeLocation, openFlags);
            SafeCertStoreHandle certStoreHandle = CAPI.CertOpenStore(new IntPtr(CAPI.CERT_STORE_PROV_SYSTEM),
                                                       CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
                                                       IntPtr.Zero,
                                                       dwOpenFlags,
                                                       this.storeName);

            if (certStoreHandle == null || certStoreHandle.IsInvalid)
            {
                int error = Marshal.GetLastWin32Error();
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(error));
            }
            this.certStoreHandle = certStoreHandle;
        }
Example #15
0
 private StorePal(SafeCertStoreHandle certStore)
 {
     _certStore = certStore;
 }
 internal static extern void _OpenX509Store(uint storeType, uint flags, string storeName, ref SafeCertStoreHandle safeCertStoreHandle);
 private static extern unsafe SafeCertContextHandle CertEnumCertificatesInStore(SafeCertStoreHandle hCertStore, CERT_CONTEXT *pPrevCertContext);
Example #18
0
 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);
 public static extern bool PFXExportCertStore(SafeCertStoreHandle hStore, [In, Out] ref CRYPTOAPI_BLOB pPFX, string szPassword, PFXExportFlags dwFlags);
Example #20
0
 public static extern bool CertControlStore(SafeCertStoreHandle hCertStore, CertControlStoreFlags dwFlags, CertControlStoreType dwControlType, IntPtr pvCtrlPara);
 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)
 {
     return(CertGetCertificateChain((IntPtr)hChainEngine, pCertContext, pTime, hStore, ref pChainPara, dwFlags, pvReserved, out ppChainContext));
 }
Example #22
0
 internal static X509Certificate2Collection GetCertificates(SafeCertStoreHandle safeCertStoreHandle) {
     X509Certificate2Collection collection = new X509Certificate2Collection();
     IntPtr pEnumContext = CAPI.CertEnumCertificatesInStore(safeCertStoreHandle, IntPtr.Zero);
     while (pEnumContext != IntPtr.Zero) {
         X509Certificate2 certificate = new X509Certificate2(pEnumContext);
         collection.Add(certificate);
         pEnumContext = CAPI.CertEnumCertificatesInStore(safeCertStoreHandle, pEnumContext);
     }
     return collection;
 }
 public static extern bool CertSaveStore(SafeCertStoreHandle hCertStore, CertEncodingType dwMsgAndCertEncodingType, CertStoreSaveAs dwSaveAs, CertStoreSaveTo dwSaveTo, ref CRYPTOAPI_BLOB pvSaveToPara, int dwFlags);
Example #24
0
 internal StorePal(SafeCertStoreHandle certStore)
 {
     _certStore = certStore;
 }
Example #25
0
 public X509Store (IntPtr storeHandle) {
     if (storeHandle == IntPtr.Zero)
         throw new ArgumentNullException("storeHandle");
     m_safeCertStoreHandle = CAPI.CertDuplicateStore(storeHandle);
     if (m_safeCertStoreHandle == null || m_safeCertStoreHandle.IsInvalid)
         throw new CryptographicException(SR.GetString(SR.Cryptography_InvalidStoreHandle), "storeHandle");
 }
Example #26
0
 internal static partial bool PFXExportCertStore(SafeCertStoreHandle hStore, ref DATA_BLOB pPFX, SafePasswordHandle szPassword, PFXExportFlags dwFlags);
Example #27
0
        public void Open(OpenFlags flags) {
            if (m_location != StoreLocation.CurrentUser && m_location != StoreLocation.LocalMachine)
                throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.Arg_EnumIllegalVal), "m_location"));

            uint storeFlags = X509Utils.MapX509StoreFlags(m_location, flags);
            if (!m_safeCertStoreHandle.IsInvalid)
                // Free the current store handle
                m_safeCertStoreHandle.Dispose();

            m_safeCertStoreHandle = CAPI.CertOpenStore(new IntPtr(CAPI.CERT_STORE_PROV_SYSTEM), 
                                                       CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
                                                       IntPtr.Zero,
                                                       storeFlags, 
                                                       m_storeName);

            if (m_safeCertStoreHandle == null || m_safeCertStoreHandle.IsInvalid)
                throw new CryptographicException(Marshal.GetLastWin32Error());

            //
            // We want the store to auto-resync when requesting a snapshot so that
            // updates to the store will be taken into account.
            //

            CAPI.CertControlStore(m_safeCertStoreHandle,
                                  0,
                                  CAPI.CERT_STORE_CTRL_AUTO_RESYNC,
                                  IntPtr.Zero);
        }
Example #28
0
        private static unsafe SafeCertStoreHandle SelectFromStore (SafeCertStoreHandle safeSourceStoreHandle, string title, string message, X509SelectionFlag selectionFlags, IntPtr hwndParent) {
            int dwErrorCode = CAPI.ERROR_SUCCESS;

            // First, create a memory store
            SafeCertStoreHandle safeCertStoreHandle = CAPI.CertOpenStore((IntPtr) CAPI.CERT_STORE_PROV_MEMORY, 
                                                                         CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, 
                                                                         IntPtr.Zero, 
                                                                         0, 
                                                                         null);

            if (safeCertStoreHandle == null || safeCertStoreHandle.IsInvalid)
                throw new CryptographicException(Marshal.GetLastWin32Error());

            CAPI.CRYPTUI_SELECTCERTIFICATE_STRUCTW csc = new CAPI.CRYPTUI_SELECTCERTIFICATE_STRUCTW();
            // Older versions of CRYPTUI do not check the size correctly,
            // so always force it to the oldest version of the structure.
            csc.dwSize = (uint) Marshal.OffsetOf(typeof(CAPI.CRYPTUI_SELECTCERTIFICATE_STRUCTW), "hSelectedCertStore");
            csc.hwndParent = hwndParent;
            csc.dwFlags = (uint) selectionFlags;
            csc.szTitle = title;
            csc.dwDontUseColumn = 0;
            csc.szDisplayString = message;
            csc.pFilterCallback = IntPtr.Zero;
            csc.pDisplayCallback = IntPtr.Zero;
            csc.pvCallbackData = IntPtr.Zero;
            csc.cDisplayStores = 1;
            IntPtr hSourceCertStore = safeSourceStoreHandle.DangerousGetHandle();
            csc.rghDisplayStores = new IntPtr(&hSourceCertStore);
            csc.cStores = 0;
            csc.rghStores = IntPtr.Zero;
            csc.cPropSheetPages = 0;
            csc.rgPropSheetPages = IntPtr.Zero;
            csc.hSelectedCertStore = safeCertStoreHandle.DangerousGetHandle();

            SafeCertContextHandle safeCertContextHandle = CAPI.CryptUIDlgSelectCertificateW(csc);

            if (safeCertContextHandle != null && !safeCertContextHandle.IsInvalid) {
                // Single select, so add it to our hCertStore
                SafeCertContextHandle ppStoreContext = SafeCertContextHandle.InvalidHandle;
                if (!CAPI.CertAddCertificateContextToStore(safeCertStoreHandle, 
                                                           safeCertContextHandle, 
                                                           CAPI.CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES, 
                                                           ppStoreContext))
                    dwErrorCode = Marshal.GetLastWin32Error();
            }

            if (dwErrorCode != CAPI.ERROR_SUCCESS)
                throw new CryptographicException(Marshal.GetLastWin32Error());

            return safeCertStoreHandle;
        }
Example #29
0
 private StorePal(SafeCertStoreHandle certStore)
 {
     _certStore = certStore;
 }
        private unsafe static SafeCertStoreHandle FindCertInStore(SafeCertStoreHandle safeSourceStoreHandle, X509FindType findType, Object findValue, bool validOnly) {
            if (findValue == null)
                throw new ArgumentNullException("findValue");

            IntPtr pvFindPara = IntPtr.Zero;
            object pvCallbackData1 = null;
            object pvCallbackData2 = null;
            FindProcDelegate pfnCertCallback1 = null;
            FindProcDelegate pfnCertCallback2 = null;
            uint dwFindType = CAPI.CERT_FIND_ANY;
            string subject, issuer;

            CAPI.CRYPTOAPI_BLOB HashBlob = new CAPI.CRYPTOAPI_BLOB();
            SafeLocalAllocHandle pb = SafeLocalAllocHandle.InvalidHandle;
            _FILETIME ft = new _FILETIME();
            string oidValue = null;

            switch(findType) {
            case X509FindType.FindByThumbprint:
                if (findValue.GetType() != typeof(string))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                byte[] hex = X509Utils.DecodeHexString((string) findValue);
                pb = X509Utils.ByteToPtr(hex);
                HashBlob.pbData = pb.DangerousGetHandle(); 
                HashBlob.cbData = (uint) hex.Length;
                dwFindType = CAPI.CERT_FIND_HASH;
                pvFindPara = new IntPtr(&HashBlob);
                break;

            case X509FindType.FindBySubjectName:
                if (findValue.GetType() != typeof(string))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                subject = (string) findValue;
                dwFindType = CAPI.CERT_FIND_SUBJECT_STR;
                pb = X509Utils.StringToUniPtr(subject);
                pvFindPara = pb.DangerousGetHandle();
                break;

            case X509FindType.FindBySubjectDistinguishedName:
                if (findValue.GetType() != typeof(string))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                subject = (string) findValue;
                pfnCertCallback1 = new FindProcDelegate(FindSubjectDistinguishedNameCallback);
                pvCallbackData1 = subject;
                break;

            case X509FindType.FindByIssuerName:
                if (findValue.GetType() != typeof(string))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                issuer = (string) findValue;
                dwFindType = CAPI.CERT_FIND_ISSUER_STR;
                pb = X509Utils.StringToUniPtr(issuer);
                pvFindPara = pb.DangerousGetHandle();
                break;

            case X509FindType.FindByIssuerDistinguishedName:
                if (findValue.GetType() != typeof(string))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                issuer = (string) findValue;
                pfnCertCallback1 = new FindProcDelegate(FindIssuerDistinguishedNameCallback);
                pvCallbackData1 = issuer;
                break;

            case X509FindType.FindBySerialNumber:
                if (findValue.GetType() != typeof(string))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                pfnCertCallback1 = new FindProcDelegate(FindSerialNumberCallback);
                pfnCertCallback2 = new FindProcDelegate(FindSerialNumberCallback);
                BigInt h = new BigInt();
                h.FromHexadecimal((string) findValue);
                pvCallbackData1 = (byte[]) h.ToByteArray();
                h.FromDecimal((string) findValue);
                pvCallbackData2 = (byte[]) h.ToByteArray();
                break;

            case X509FindType.FindByTimeValid:
                if (findValue.GetType() != typeof(DateTime))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                *((long*) &ft) = ((DateTime) findValue).ToFileTime();
                pfnCertCallback1 = new FindProcDelegate(FindTimeValidCallback);
                pvCallbackData1 = ft; 
                break;

            case X509FindType.FindByTimeNotYetValid:
                if (findValue.GetType() != typeof(DateTime))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                *((long*) &ft) = ((DateTime) findValue).ToFileTime();
                pfnCertCallback1 = new FindProcDelegate(FindTimeNotBeforeCallback);
                pvCallbackData1 = ft; 
                break;

            case X509FindType.FindByTimeExpired:
                if (findValue.GetType() != typeof(DateTime))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                *((long*) &ft) = ((DateTime) findValue).ToFileTime();
                pfnCertCallback1 = new FindProcDelegate(FindTimeNotAfterCallback);
                pvCallbackData1 = ft; 
                break;

            case X509FindType.FindByTemplateName:
                if (findValue.GetType() != typeof(string))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                pvCallbackData1 = (string) findValue; 
                pfnCertCallback1 = new FindProcDelegate(FindTemplateNameCallback);
                break;

            case X509FindType.FindByApplicationPolicy:
                if (findValue.GetType() != typeof(string))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                // If we were passed the friendly name, retrieve the value string.
                oidValue = X509Utils.FindOidInfoWithFallback(CAPI.CRYPT_OID_INFO_NAME_KEY, (string) findValue, OidGroup.Policy);
                if (oidValue == null) {
                    oidValue = (string) findValue;
                    X509Utils.ValidateOidValue(oidValue);
                }
                pvCallbackData1 = oidValue;
                pfnCertCallback1 = new FindProcDelegate(FindApplicationPolicyCallback);
                break;

            case X509FindType.FindByCertificatePolicy:
                if (findValue.GetType() != typeof(string))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                // If we were passed the friendly name, retrieve the value string.
                oidValue = X509Utils.FindOidInfoWithFallback(CAPI.CRYPT_OID_INFO_NAME_KEY, (string)findValue, OidGroup.Policy);
                if (oidValue == null) {
                    oidValue = (string) findValue;
                    X509Utils.ValidateOidValue(oidValue);
                }
                pvCallbackData1 = oidValue;
                pfnCertCallback1 = new FindProcDelegate(FindCertificatePolicyCallback);
                break;

            case X509FindType.FindByExtension:
                if (findValue.GetType() != typeof(string))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                // If we were passed the friendly name, retrieve the value string.
                oidValue = X509Utils.FindOidInfoWithFallback(CAPI.CRYPT_OID_INFO_NAME_KEY, (string)findValue, OidGroup.ExtensionOrAttribute);
                if (oidValue == null) {
                    oidValue = (string) findValue;
                    X509Utils.ValidateOidValue(oidValue);
                }
                pvCallbackData1 = oidValue;
                pfnCertCallback1 = new FindProcDelegate(FindExtensionCallback);
                break;

            case X509FindType.FindByKeyUsage:
                // The findValue object can be either a friendly name, a X509KeyUsageFlags enum or an integer.
                if (findValue.GetType() == typeof(string)) {
                    CAPI.KEY_USAGE_STRUCT[] KeyUsages = new CAPI.KEY_USAGE_STRUCT[] { 
                        new CAPI.KEY_USAGE_STRUCT("DigitalSignature", CAPI.CERT_DIGITAL_SIGNATURE_KEY_USAGE),
                        new CAPI.KEY_USAGE_STRUCT("NonRepudiation",   CAPI.CERT_NON_REPUDIATION_KEY_USAGE),
                        new CAPI.KEY_USAGE_STRUCT("KeyEncipherment",  CAPI.CERT_KEY_ENCIPHERMENT_KEY_USAGE),
                        new CAPI.KEY_USAGE_STRUCT("DataEncipherment", CAPI.CERT_DATA_ENCIPHERMENT_KEY_USAGE),
                        new CAPI.KEY_USAGE_STRUCT("KeyAgreement",     CAPI.CERT_KEY_AGREEMENT_KEY_USAGE),
                        new CAPI.KEY_USAGE_STRUCT("KeyCertSign",      CAPI.CERT_KEY_CERT_SIGN_KEY_USAGE),
                        new CAPI.KEY_USAGE_STRUCT("CrlSign",          CAPI.CERT_CRL_SIGN_KEY_USAGE),
                        new CAPI.KEY_USAGE_STRUCT("EncipherOnly",     CAPI.CERT_ENCIPHER_ONLY_KEY_USAGE),
                        new CAPI.KEY_USAGE_STRUCT("DecipherOnly",     CAPI.CERT_DECIPHER_ONLY_KEY_USAGE)
                    };

                    for (uint index = 0; index < KeyUsages.Length; index++) {
                        if (String.Compare(KeyUsages[index].pwszKeyUsage, (string) findValue, StringComparison.OrdinalIgnoreCase) == 0) {
                            pvCallbackData1 = KeyUsages[index].dwKeyUsageBit;
                            break;
                        }
                    }
                    if (pvCallbackData1 == null)
                        throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindType));
                } else if (findValue.GetType() == typeof(X509KeyUsageFlags)) {
                    pvCallbackData1 = findValue;
                } else if (findValue.GetType() == typeof(uint) || findValue.GetType() == typeof(int)) {
                    // We got the actual DWORD
                    pvCallbackData1 = findValue;
                } else 
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindType));

                pfnCertCallback1 = new FindProcDelegate(FindKeyUsageCallback);
                break;

            case X509FindType.FindBySubjectKeyIdentifier:
                if (findValue.GetType() != typeof(string))
                    throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue));
                pvCallbackData1 = (byte[]) X509Utils.DecodeHexString((string) findValue);
                pfnCertCallback1 = new FindProcDelegate(FindSubjectKeyIdentifierCallback);
                break;

            default:
                throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindType));
            }

            // First, create a memory store
            SafeCertStoreHandle safeTargetStoreHandle = CAPI.CertOpenStore(new IntPtr(CAPI.CERT_STORE_PROV_MEMORY), 
                                                                           CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, 
                                                                           IntPtr.Zero, 
                                                                           CAPI.CERT_STORE_ENUM_ARCHIVED_FLAG | CAPI.CERT_STORE_CREATE_NEW_FLAG, 
                                                                           null);
            if (safeTargetStoreHandle == null || safeTargetStoreHandle.IsInvalid)
                throw new CryptographicException(Marshal.GetLastWin32Error());

            // FindByCert will throw an exception in case of failures.
            FindByCert(safeSourceStoreHandle, 
                       dwFindType,
                       pvFindPara, 
                       validOnly, 
                       pfnCertCallback1,
                       pfnCertCallback2, 
                       pvCallbackData1,
                       pvCallbackData2, 
                       safeTargetStoreHandle);

            pb.Dispose();
            return safeTargetStoreHandle;
        }
Example #31
0
 public static extern bool PFXExportCertStore(SafeCertStoreHandle hStore, [In, Out] ref CRYPTOAPI_BLOB pPFX, String szPassword, PFXExportFlags dwFlags);
Example #32
0
        // 
        // private static methods
        //

        private static void RemoveCertificateFromStore(SafeCertStoreHandle safeCertStoreHandle, SafeCertContextHandle safeCertContext) {
            if (safeCertContext == null || safeCertContext.IsInvalid)
                return;

            if (safeCertStoreHandle == null || safeCertStoreHandle.IsInvalid || safeCertStoreHandle.IsClosed)
                throw new CryptographicException(SR.GetString(SR.Cryptography_X509_StoreNotOpen));

            // Find the certificate in the store.
            SafeCertContextHandle safeCertContext2 = CAPI.CertFindCertificateInStore(safeCertStoreHandle, 
                                                                                     CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
                                                                                     0, 
                                                                                     CAPI.CERT_FIND_EXISTING, 
                                                                                     safeCertContext.DangerousGetHandle(),
                                                                                     SafeCertContextHandle.InvalidHandle);

            // The certificate is not present in the store, simply return.
            if (safeCertContext2 == null || safeCertContext2.IsInvalid)
                return;

            // CertDeleteCertificateFromStore always releases the context regardless of success 
            // or failure so we don't need to manually release it
            GC.SuppressFinalize(safeCertContext2);

            // Remove from the store.
            if (!CAPI.CertDeleteCertificateFromStore(safeCertContext2))
                throw new CryptographicException(Marshal.GetLastWin32Error());
        }
 internal static extern byte[] _ExportCertificatesToBlob(SafeCertStoreHandle safeCertStoreHandle, X509ContentType contentType, IntPtr password);
Example #34
0
 private static extern unsafe SafeCertContextHandle CertEnumCertificatesInStore(SafeCertStoreHandle hCertStore, CERT_CONTEXT* pPrevCertContext);
Example #35
0
 internal static X509Certificate2Collection GetCertificates(SafeCertStoreHandle safeCertStoreHandle)
 {
     X509Certificate2Collection certificate2Collection = new X509Certificate2Collection();
     for (IntPtr index = CAPI.CertEnumCertificatesInStore(safeCertStoreHandle, IntPtr.Zero); index != IntPtr.Zero; index = CAPI.CertEnumCertificatesInStore(safeCertStoreHandle, index))
     {
         X509Certificate2 certificate = new X509Certificate2(index);
         certificate2Collection.Add(certificate);
     }
     return certificate2Collection;
 }
Example #36
0
 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)
 {
     return CertGetCertificateChain((IntPtr)hChainEngine, pCertContext, pTime, hStore, ref pChainPara, dwFlags, pvReserved, out ppChainContext);
 }
Example #37
0
 private static unsafe partial CERT_CONTEXT *CertEnumCertificatesInStore(SafeCertStoreHandle hCertStore, CERT_CONTEXT *pPrevCertContext);
Example #38
0
 public static extern bool CertSaveStore(SafeCertStoreHandle hCertStore, CertEncodingType dwMsgAndCertEncodingType, CertStoreSaveAs dwSaveAs, CertStoreSaveTo dwSaveTo, ref CRYPTOAPI_BLOB pvSaveToPara, int dwFlags);
Example #39
0
 public static unsafe partial bool CertGetCertificateChain(IntPtr hChainEngine, SafeCertContextHandle pCertContext, FILETIME *pTime, SafeCertStoreHandle hStore, ref CERT_CHAIN_PARA pChainPara, CertChainFlags dwFlags, IntPtr pvReserved, out SafeX509ChainHandle ppChainContext);
Example #40
0
 private static unsafe extern SafeCertContextHandle CertFindCertificateInStore(SafeCertStoreHandle hCertStore, CertEncodingType dwCertEncodingType, CertFindFlags dwFindFlags, CertFindType dwFindType, void* pvFindPara, CERT_CONTEXT* pPrevCertContext);
Example #41
0
 public static partial bool CertSaveStore(SafeCertStoreHandle hCertStore, CertEncodingType dwMsgAndCertEncodingType, CertStoreSaveAs dwSaveAs, CertStoreSaveTo dwSaveTo, ref DATA_BLOB pvSaveToPara, int dwFlags);
Example #42
0
 private static unsafe partial SafeCertContextHandle CertFindCertificateInStore(SafeCertStoreHandle hCertStore, CertEncodingType dwCertEncodingType, CertFindFlags dwFindFlags, CertFindType dwFindType, void *pvFindPara, CERT_CONTEXT *pPrevCertContext);
Example #43
0
 public static partial bool CertControlStore(SafeCertStoreHandle hCertStore, CertControlStoreFlags dwFlags, CertControlStoreType dwControlType, IntPtr pvCtrlPara);
Example #44
0
 internal StorePal(SafeCertStoreHandle certStore)
 {
     _certStore = certStore;
 }
Example #45
0
 public static partial bool CertAddCertificateLinkToStore(SafeCertStoreHandle hCertStore, SafeCertContextHandle pCertContext, CertStoreAddDisposition dwAddDisposition, IntPtr ppStoreContext);
Example #46
0
        private static SafeCertContextHandle GetSignerInPKCS7Store(SafeCertStoreHandle hCertStore, SafeCryptMsgHandle hCryptMsg)
        {
            // make sure that there is at least one signer of the certificate store
            int dwSigners;
            int cbSigners = sizeof(int);
            if (!Interop.crypt32.CryptMsgGetParam(hCryptMsg, CryptMessageParameterType.CMSG_SIGNER_COUNT_PARAM, 0, out dwSigners, ref cbSigners))
                throw Marshal.GetHRForLastWin32Error().ToCryptographicException();;
            if (dwSigners == 0)
                throw ErrorCode.CRYPT_E_SIGNER_NOT_FOUND.ToCryptographicException();

            // get the first signer from the store, and use that as the loaded certificate
            int cbData = 0;
            if (!Interop.crypt32.CryptMsgGetParam(hCryptMsg, CryptMessageParameterType.CMSG_SIGNER_INFO_PARAM, 0, null, ref cbData))
                throw Marshal.GetHRForLastWin32Error().ToCryptographicException();;

            byte[] cmsgSignerBytes = new byte[cbData];
            if (!Interop.crypt32.CryptMsgGetParam(hCryptMsg, CryptMessageParameterType.CMSG_SIGNER_INFO_PARAM, 0, cmsgSignerBytes, ref cbData))
                throw Marshal.GetHRForLastWin32Error().ToCryptographicException();;

            CERT_INFO certInfo = default(CERT_INFO);
            unsafe
            {
                fixed (byte* pCmsgSignerBytes = cmsgSignerBytes)
                {
                    CMSG_SIGNER_INFO_Partial* pCmsgSignerInfo = (CMSG_SIGNER_INFO_Partial*)pCmsgSignerBytes;
                    certInfo.Issuer.cbData = pCmsgSignerInfo->Issuer.cbData;
                    certInfo.Issuer.pbData = pCmsgSignerInfo->Issuer.pbData;
                    certInfo.SerialNumber.cbData = pCmsgSignerInfo->SerialNumber.cbData;
                    certInfo.SerialNumber.pbData = pCmsgSignerInfo->SerialNumber.pbData;
                }

                SafeCertContextHandle pCertContext = null;
                if (!Interop.crypt32.CertFindCertificateInStore(hCertStore, CertFindType.CERT_FIND_SUBJECT_CERT, &certInfo, ref pCertContext))
                    throw Marshal.GetHRForLastWin32Error().ToCryptographicException();;

                return pCertContext;
            }
        }
 internal static extern bool CertAddCertificateLinkToStore(SafeCertStoreHandle hCertStore, SafeCertContextHandle pCertContext, uint dwAddDisposition, [In, Out] SafeCertContextHandle ppStoreContext);