private static unsafe SafeCertStoreHandle SelectFromStore(SafeCertStoreHandle safeSourceStoreHandle, string title, string message, X509SelectionFlag selectionFlags, IntPtr hwndParent)
        {
            int dwErrorCode = ERROR_SUCCESS;

            SafeCertStoreHandle safeCertStoreHandle = Interop.Crypt32.CertOpenStore(
                (IntPtr)Interop.Crypt32.CERT_STORE_PROV_MEMORY,
                Interop.Crypt32.X509_ASN_ENCODING | Interop.Crypt32.PKCS_7_ASN_ENCODING,
                IntPtr.Zero,
                0,
                null);

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

            Interop.CryptUI.CRYPTUI_SELECTCERTIFICATE_STRUCTW csc = new Interop.CryptUI.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(Interop.CryptUI.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 = Interop.CryptUI.CryptUIDlgSelectCertificateW(csc);

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

            if (dwErrorCode != ERROR_SUCCESS)
            {
                throw new CryptographicException(dwErrorCode);
            }

            return(safeCertStoreHandle);
        }
        private static SafeChainEngineHandle GetChainEngine(
            X509ChainTrustMode trustMode,
            X509Certificate2Collection?customTrustStore,
            bool useMachineContext)
        {
            SafeChainEngineHandle chainEngineHandle;

            if (trustMode == X509ChainTrustMode.CustomRootTrust)
            {
                // Need to get a valid SafeCertStoreHandle otherwise the default stores will be trusted
                using (SafeCertStoreHandle customTrustStoreHandle = ConvertStoreToSafeHandle(customTrustStore, true))
                {
                    Interop.Crypt32.CERT_CHAIN_ENGINE_CONFIG customChainEngine = default;
                    customChainEngine.cbSize         = Marshal.SizeOf <Interop.Crypt32.CERT_CHAIN_ENGINE_CONFIG>();
                    customChainEngine.hExclusiveRoot = customTrustStoreHandle.DangerousGetHandle();
                    chainEngineHandle = Interop.crypt32.CertCreateCertificateChainEngine(ref customChainEngine);
                }
            }
            else
            {
                chainEngineHandle = useMachineContext ? SafeChainEngineHandle.MachineChainEngine : SafeChainEngineHandle.UserChainEngine;
            }

            return(chainEngineHandle);
        }
Beispiel #3
0
        private static unsafe SafeCertStoreHandle SelectFromStore(SafeCertStoreHandle safeSourceStoreHandle, string?title, string?message, X509SelectionFlag selectionFlags, IntPtr hwndParent)
        {
            int dwErrorCode = ERROR_SUCCESS;

            SafeCertStoreHandle safeCertStoreHandle = Interop.Crypt32.CertOpenStore(
                (IntPtr)Interop.Crypt32.CERT_STORE_PROV_MEMORY,
                Interop.Crypt32.X509_ASN_ENCODING | Interop.Crypt32.PKCS_7_ASN_ENCODING,
                IntPtr.Zero,
                0,
                IntPtr.Zero);

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

            Interop.CryptUI.CRYPTUI_SELECTCERTIFICATE_STRUCTW csc = default;
            // Older versions of CRYPTUI do not check the size correctly,
            // so always force it to the oldest version of the structure.
#if NET7_0_OR_GREATER
            // Declare a local for Native to enable us to get the managed byte offset
            // without having a null check cause a failure.
            Interop.CryptUI.CRYPTUI_SELECTCERTIFICATE_STRUCTW.Marshaller.Native native;
            Unsafe.SkipInit(out native);
            csc.dwSize = (uint)Unsafe.ByteOffset(ref Unsafe.As <Interop.CryptUI.CRYPTUI_SELECTCERTIFICATE_STRUCTW.Marshaller.Native, byte>(ref native), ref Unsafe.As <IntPtr, byte>(ref native.hSelectedCertStore));
#else
            csc.dwSize = (uint)Marshal.OffsetOf(typeof(Interop.CryptUI.CRYPTUI_SELECTCERTIFICATE_STRUCTW), "hSelectedCertStore");
#endif
            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 = Interop.CryptUI.CryptUIDlgSelectCertificateW(ref csc);

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

            if (dwErrorCode != ERROR_SUCCESS)
            {
                throw new CryptographicException(dwErrorCode);
            }

            return(safeCertStoreHandle);
        }