Пример #1
0
        internal static unsafe X509Certificate2 CreateDummyCertificate(CspParameters parameters)
        {
            System.Security.Cryptography.SafeCertContextHandle invalidHandle = System.Security.Cryptography.SafeCertContextHandle.InvalidHandle;
            SafeCryptProvHandle hCryptProv = SafeCryptProvHandle.InvalidHandle;
            uint dwFlags = 0U;

            if ((parameters.Flags & CspProviderFlags.UseMachineKeyStore) != CspProviderFlags.NoFlags)
            {
                dwFlags |= 32U;
            }
            if ((parameters.Flags & CspProviderFlags.UseDefaultKeyContainer) != CspProviderFlags.NoFlags)
            {
                dwFlags |= 4026531840U;
            }
            if ((parameters.Flags & CspProviderFlags.NoPrompt) != CspProviderFlags.NoFlags)
            {
                dwFlags |= 64U;
            }
            if (!CAPI.CryptAcquireContext(ref hCryptProv, parameters.KeyContainerName, parameters.ProviderName, (uint)parameters.ProviderType, dwFlags))
            {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }
            CAPI.CRYPT_KEY_PROV_INFO cryptKeyProvInfo = new CAPI.CRYPT_KEY_PROV_INFO();
            cryptKeyProvInfo.pwszProvName      = parameters.ProviderName;
            cryptKeyProvInfo.pwszContainerName = parameters.KeyContainerName;
            cryptKeyProvInfo.dwProvType        = (uint)parameters.ProviderType;
            cryptKeyProvInfo.dwKeySpec         = (uint)parameters.KeyNumber;
            cryptKeyProvInfo.dwFlags           = (parameters.Flags & CspProviderFlags.UseMachineKeyStore) == CspProviderFlags.UseMachineKeyStore ? 32U : 0U;
            SafeLocalAllocHandle localAllocHandle1 = CAPI.LocalAlloc(64U, new IntPtr(Marshal.SizeOf(typeof(CAPI.CRYPT_KEY_PROV_INFO))));

            Marshal.StructureToPtr((object)cryptKeyProvInfo, localAllocHandle1.DangerousGetHandle(), false);
            CAPI.CRYPT_ALGORITHM_IDENTIFIER algorithmIdentifier = new CAPI.CRYPT_ALGORITHM_IDENTIFIER();
            algorithmIdentifier.pszObjId = "1.3.14.3.2.29";
            SafeLocalAllocHandle localAllocHandle2 = CAPI.LocalAlloc(64U, new IntPtr(Marshal.SizeOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER))));

            Marshal.StructureToPtr((object)algorithmIdentifier, localAllocHandle2.DangerousGetHandle(), false);
            X500DistinguishedName distinguishedName = new X500DistinguishedName("cn=CMS Signer Dummy Certificate");

            System.Security.Cryptography.SafeCertContextHandle selfSignCertificate;

            fixed(byte *numPtr = distinguishedName.RawData)
            selfSignCertificate = CAPI.CAPIUnsafe.CertCreateSelfSignCertificate(hCryptProv, new IntPtr((void *)&new CAPI.CRYPTOAPI_BLOB()
            {
                cbData = (uint)distinguishedName.RawData.Length,
                pbData = new IntPtr((void *)numPtr)
            }), 1U, localAllocHandle1.DangerousGetHandle(), localAllocHandle2.DangerousGetHandle(), IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);

            Marshal.DestroyStructure(localAllocHandle1.DangerousGetHandle(), typeof(CAPI.CRYPT_KEY_PROV_INFO));
            localAllocHandle1.Dispose();
            Marshal.DestroyStructure(localAllocHandle2.DangerousGetHandle(), typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER));
            localAllocHandle2.Dispose();
            if (selfSignCertificate == null || selfSignCertificate.IsInvalid)
            {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }
            X509Certificate2 x509Certificate2 = new X509Certificate2(selfSignCertificate.DangerousGetHandle());

            selfSignCertificate.Dispose();
            return(x509Certificate2);
        }
        internal static bool GetPrivateKeyInfo(SafeCertContextHandle safeCertContext, ref CspParameters parameters)
        {
            SafeLocalAllocHandle ptr = SafeLocalAllocHandle.InvalidHandle;
            uint cbData = 0;

            if (!CAPI.CAPISafe.CertGetCertificateContextProperty(safeCertContext,
                                                                 CAPI.CERT_KEY_PROV_INFO_PROP_ID,
                                                                 ptr,
                                                                 ref cbData))
            {
                int dwErrorCode = Marshal.GetLastWin32Error();
                if (dwErrorCode == CAPI.CRYPT_E_NOT_FOUND)
                {
                    return(false);
                }
                else
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }
            }

            ptr = CAPI.LocalAlloc(CAPI.LMEM_FIXED, new IntPtr(cbData));
            if (!CAPI.CAPISafe.CertGetCertificateContextProperty(safeCertContext,
                                                                 CAPI.CERT_KEY_PROV_INFO_PROP_ID,
                                                                 ptr,
                                                                 ref cbData))
            {
                int dwErrorCode = Marshal.GetLastWin32Error();
                if (dwErrorCode == CAPI.CRYPT_E_NOT_FOUND)
                {
                    return(false);
                }
                else
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }
            }

            CAPI.CRYPT_KEY_PROV_INFO pKeyProvInfo = (CAPI.CRYPT_KEY_PROV_INFO)Marshal.PtrToStructure(ptr.DangerousGetHandle(), typeof(CAPI.CRYPT_KEY_PROV_INFO));
            parameters.ProviderName     = pKeyProvInfo.pwszProvName;
            parameters.KeyContainerName = pKeyProvInfo.pwszContainerName;
            parameters.ProviderType     = (int)pKeyProvInfo.dwProvType;
            parameters.KeyNumber        = (int)pKeyProvInfo.dwKeySpec;
            parameters.Flags            = (CspProviderFlags)((pKeyProvInfo.dwFlags & CAPI.CRYPT_MACHINE_KEYSET) == CAPI.CRYPT_MACHINE_KEYSET ? CspProviderFlags.UseMachineKeyStore : 0);

            ptr.Dispose();
            return(true);
        }
Пример #3
0
        internal static bool GetPrivateKeyInfo(System.Security.Cryptography.SafeCertContextHandle safeCertContext, ref CspParameters parameters)
        {
            SafeLocalAllocHandle invalidHandle = SafeLocalAllocHandle.InvalidHandle;
            uint pcbData = 0U;

            if (!CAPI.CAPISafe.CertGetCertificateContextProperty(safeCertContext, 2U, invalidHandle, out pcbData))
            {
                if (Marshal.GetLastWin32Error() == -2146885628)
                {
                    return(false);
                }
                else
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }
            }
            else
            {
                SafeLocalAllocHandle pvData = CAPI.LocalAlloc(0U, new IntPtr((long)pcbData));
                if (!CAPI.CAPISafe.CertGetCertificateContextProperty(safeCertContext, 2U, pvData, out pcbData))
                {
                    if (Marshal.GetLastWin32Error() == -2146885628)
                    {
                        return(false);
                    }
                    else
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }
                }
                else
                {
                    CAPI.CRYPT_KEY_PROV_INFO cryptKeyProvInfo = (CAPI.CRYPT_KEY_PROV_INFO)Marshal.PtrToStructure(pvData.DangerousGetHandle(), typeof(CAPI.CRYPT_KEY_PROV_INFO));
                    parameters.ProviderName     = cryptKeyProvInfo.pwszProvName;
                    parameters.KeyContainerName = cryptKeyProvInfo.pwszContainerName;
                    parameters.ProviderType     = (int)cryptKeyProvInfo.dwProvType;
                    parameters.KeyNumber        = (int)cryptKeyProvInfo.dwKeySpec;
                    parameters.Flags            = ((int)cryptKeyProvInfo.dwFlags & 32) == 32 ? CspProviderFlags.UseMachineKeyStore : CspProviderFlags.NoFlags;
                    pvData.Dispose();
                    return(true);
                }
            }
        }
Пример #4
0
        /// <summary>
        /// If the certificate has private key, this cert can be used for signing, if it does not,
        /// try to access private key stored in the CSP, if CSP provider or key container name
        /// is not provided, certificate can't be used for signing.
        /// </summary>
        /// <param name="certificate">Certificate</param>
        /// <param name="cryptoProviderName">Crypto provider name</param>
        /// <param name="keyContainerName">Key container name</param>
        /// <param name="providerType">Provider type</param>
        /// <returns></returns>
        public static bool SetPrivateKeyIfNeeded(X509Certificate2 certificate, string cryptoProviderName, string keyContainerName, int providerType = -1)
        {
            if (Certificate.HasPrivateKey(certificate))
            {
                // We got a .pfx file.
                // Silently ignore CSP name or key container if either was provided with a .pfx fle.
                return(true);
            }

            // If provider and key container names are specified, try to access private key.
            if (cryptoProviderName != null && keyContainerName != null)
            {
                try
                {
                    bool result = true;

                    if (providerType == PROV_UNINITIALIZED)
                    {
                        providerType = Certificate.GetCspType(cryptoProviderName);
                    }

                    if (providerType == PROV_UNINITIALIZED)
                    {
                        return(false);
                    }

                    // The following code will modify state of certificates from x509Store,
                    // make sure to assign private keys only to certificates that were created from a .cer files
                    if (providerType != 0)
                    {
                        CspParameters parameters;
                        parameters = new CspParameters
                        {
                            ProviderName     = cryptoProviderName,
                            ProviderType     = providerType,
                            KeyContainerName = keyContainerName,
                            KeyNumber        = (int)KeyNumber.Signature,
                            // Make sure key creation is not attempted.
                            Flags = CspProviderFlags.UseExistingKey
                        };

                        if (IsMachineCryptKey(cryptoProviderName, (uint)providerType, keyContainerName))
                        {
                            // Search only Machine key store for this private key, if not set we search only user store.
                            parameters.Flags |= CspProviderFlags.UseMachineKeyStore;
                        }

                        certificate.PrivateKey = new RSACryptoServiceProvider(parameters);
                    }
                    else
                    {
                        CAPI.CRYPT_KEY_PROV_INFO keyProvInfo = new CAPI.CRYPT_KEY_PROV_INFO
                        {
                            pwszProvName      = cryptoProviderName,
                            pwszContainerName = keyContainerName,
                            dwProvType        = (uint)providerType,
                            dwKeySpec         = (int)KeyNumber.Signature,
                            dwFlags           = IsMachineNCryptKey(cryptoProviderName, keyContainerName) ? NCryptMethods.NCRYPT_MACHINE_KEY_FLAG : (uint)0
                        };

                        using (SafeLocalAllocHandle pKeyProvInfo = CAPI.LocalAlloc(CAPI.LPTR, (uint)Marshal.SizeOf(typeof(CAPI.CRYPT_KEY_PROV_INFO))))
                        {
                            Marshal.StructureToPtr(keyProvInfo, pKeyProvInfo.DangerousGetHandle(), false);
                            result = CAPI.CertSetKeyProviderInfoProperty(certificate.Handle, pKeyProvInfo);
                            Marshal.DestroyStructure(pKeyProvInfo.DangerousGetHandle(), typeof(CAPI.CRYPT_KEY_PROV_INFO));
                        }
                    }

                    return(result);
                }
                catch (Exception e)
                {
                    if (Misc.IsCriticalException(e))
                    {
                        throw;
                    }
                    // Caller displays an error message.
                    System.Diagnostics.Debug.WriteLine(e.Message);
                }
            }

            return(false);
        }