示例#1
0
 public static extern IntPtr CertCreateSelfSignCertificate(
     IntPtr providerHandle,
     [In] ref CryptoApiBlob subjectIssuerBlob,
     int flags,
     [In] ref CryptKeyProviderInformation keyProviderInformation,
     IntPtr signatureAlgorithm,
     [In] ref SystemTime startTime,
     [In] ref SystemTime endTime,
     IntPtr extensions);
示例#2
0
 internal static extern IntPtr CertCreateSelfSignCertificate(
     IntPtr providerHandle,
     [In] CryptoApiBlob subjectIssuerBlob,
     int flags,
     ref CRYPT_KEY_PROV_INFO pKeyProvInfo,
     ref CRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm,
     [In] SystemTime startTime,
     [In] SystemTime endTime,
     IntPtr extensions);
 internal static extern CertificateHandle CertCreateSelfSignCertificate(
     KeyContainerHandle hProv,
     CryptoApiBlob pSubjectIssuerBlob,
     SelfSignFlags dwFlags,
     IntPtr pKeyProvInfo,
     IntPtr pSignatureAlgorithm,
     [In] ref SystemTime pStartTime,
     [In] ref SystemTime pEndTime,
     IntPtr pExtensions);
示例#4
0
        private static byte[] ExportCertificate(IntPtr certStore, SecureString password)
        {
            GCHandle dataHandle  = new GCHandle();
            IntPtr   passwordPtr = IntPtr.Zero;

            if (password != null)
            {
                passwordPtr = Marshal.SecureStringToCoTaskMemUnicode(password);
            }

            try
            {
                byte[]        pfxData;
                CryptoApiBlob pfxBlob = new CryptoApiBlob();
                Check(NativeMethods.PFXExportCertStoreEx(
                          certStore,
                          ref pfxBlob,
                          passwordPtr,
                          IntPtr.Zero,
                          7));               // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY

                pfxData      = new byte[pfxBlob.DataLength];
                dataHandle   = GCHandle.Alloc(pfxData, GCHandleType.Pinned);
                pfxBlob.Data = dataHandle.AddrOfPinnedObject();
                Check(NativeMethods.PFXExportCertStoreEx(
                          certStore,
                          ref pfxBlob,
                          passwordPtr,
                          IntPtr.Zero,
                          7));               // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY

                return(pfxData);
            }
            finally
            {
                if (passwordPtr != IntPtr.Zero)
                {
                    Marshal.ZeroFreeCoTaskMemUnicode(passwordPtr);
                }

                if (dataHandle.IsAllocated)
                {
                    dataHandle.Free();
                }
            }
        }
示例#5
0
        /// <summary>建立自签名证书</summary>
        /// <param name="distName"></param>
        /// <param name="startTime"></param>
        /// <param name="endTime"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public static Byte[] CreateSelfSignCertificatePfx(X500DistinguishedName distName, DateTime startTime, DateTime endTime, SecureString password)
        {
            var containerName = Guid.NewGuid().ToString();

            var dataHandle       = new GCHandle();
            var providerContext  = IntPtr.Zero;
            var cryptKey         = IntPtr.Zero;
            var certContext      = IntPtr.Zero;
            var certStore        = IntPtr.Zero;
            var storeCertContext = IntPtr.Zero;
            var passwordPtr      = IntPtr.Zero;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                Check(NativeMethods.CryptAcquireContextW(
                          out providerContext,
                          containerName,
                          null,
                          1,   // PROV_RSA_FULL
                          8)); // CRYPT_NEWKEYSET

                Check(NativeMethods.CryptGenKey(
                          providerContext,
                          1, // AT_KEYEXCHANGE
                          1, // CRYPT_EXPORTABLE
                          out cryptKey));

                var nameData = distName.RawData;

                dataHandle = GCHandle.Alloc(nameData, GCHandleType.Pinned);
                var nameBlob = new CryptoApiBlob(nameData.Length, dataHandle.AddrOfPinnedObject());

                var kpi = new CryptKeyProviderInformation
                {
                    ContainerName = containerName,
                    ProviderType  = 1, // PROV_RSA_FULL
                    KeySpec       = 1  // AT_KEYEXCHANGE
                };

                var startSystemTime = ToSystemTime(startTime);
                var endSystemTime   = ToSystemTime(endTime);
                certContext = NativeMethods.CertCreateSelfSignCertificate(
                    providerContext,
                    ref nameBlob,
                    0,
                    ref kpi,
                    IntPtr.Zero, // default = SHA1RSA
                    ref startSystemTime,
                    ref endSystemTime,
                    IntPtr.Zero);
                Check(certContext != IntPtr.Zero);
                dataHandle.Free();

                certStore = NativeMethods.CertOpenStore(
                    "Memory", // sz_CERT_STORE_PROV_MEMORY
                    0,
                    IntPtr.Zero,
                    0x2000, // CERT_STORE_CREATE_NEW_FLAG
                    IntPtr.Zero);
                Check(certStore != IntPtr.Zero);

                Check(NativeMethods.CertAddCertificateContextToStore(
                          certStore,
                          certContext,
                          1, // CERT_STORE_ADD_NEW
                          out storeCertContext));

                NativeMethods.CertSetCertificateContextProperty(
                    storeCertContext,
                    2, // CERT_KEY_PROV_INFO_PROP_ID
                    0,
                    ref kpi);

                if (password != null)
                {
                    passwordPtr = Marshal.SecureStringToCoTaskMemUnicode(password);
                }

                var pfxBlob = new CryptoApiBlob();
                Check(NativeMethods.PFXExportCertStoreEx(
                          certStore,
                          ref pfxBlob,
                          passwordPtr,
                          IntPtr.Zero,
                          7)); // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY

                var pfxData = new Byte[pfxBlob.DataLength];
                dataHandle   = GCHandle.Alloc(pfxData, GCHandleType.Pinned);
                pfxBlob.Data = dataHandle.AddrOfPinnedObject();
                Check(NativeMethods.PFXExportCertStoreEx(
                          certStore,
                          ref pfxBlob,
                          passwordPtr,
                          IntPtr.Zero,
                          7)); // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY
                dataHandle.Free();

                return(pfxData);
            }
            finally
            {
                if (passwordPtr != IntPtr.Zero)
                {
                    Marshal.ZeroFreeCoTaskMemUnicode(passwordPtr);
                }

                if (dataHandle.IsAllocated)
                {
                    dataHandle.Free();
                }

                if (certContext != IntPtr.Zero)
                {
                    NativeMethods.CertFreeCertificateContext(certContext);
                }

                if (storeCertContext != IntPtr.Zero)
                {
                    NativeMethods.CertFreeCertificateContext(storeCertContext);
                }

                if (certStore != IntPtr.Zero)
                {
                    NativeMethods.CertCloseStore(certStore, 0);
                }

                if (cryptKey != IntPtr.Zero)
                {
                    NativeMethods.CryptDestroyKey(cryptKey);
                }

                if (providerContext != IntPtr.Zero)
                {
                    NativeMethods.CryptReleaseContext(providerContext, 0);
                    NativeMethods.CryptAcquireContextW(
                        out providerContext,
                        containerName,
                        null,
                        1,     // PROV_RSA_FULL
                        0x10); // CRYPT_DELETEKEYSET
                }
            }
        }
        public static X509Certificate2 GenerateSelfSignedCertificate(String name = "", DateTime?startTime = null, DateTime?endTime = null)
        {
            if (startTime == null || (DateTime)startTime < DateTime.FromFileTimeUtc(0))
            {
                startTime = DateTime.FromFileTimeUtc(0);
            }
            var startSystemTime = ((DateTime)startTime).ToSystemTime();

            if (endTime == null)
            {
                endTime = DateTime.MaxValue;
            }
            var      endSystemTime      = ((DateTime)endTime).ToSystemTime();
            string   containerName      = Guid.NewGuid().ToString();
            GCHandle dataHandle         = new GCHandle();
            IntPtr   providerContext    = IntPtr.Zero;
            IntPtr   cryptKey           = IntPtr.Zero;
            IntPtr   certificateContext = IntPtr.Zero;
            IntPtr   algorithmPointer   = IntPtr.Zero;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                MarshalHelper.CheckReturnValue(CryptAcquireContextW(out providerContext, containerName, null, 0x18, 0x8));
                MarshalHelper.CheckReturnValue(CryptGenKey(providerContext, 0x6610, 0x4000001, out cryptKey));
                IntPtr errorStringPtr;
                int    nameDataLength = 0;
                byte[] nameData;
                dataHandle = GCHandle.Alloc(name, GCHandleType.Pinned);
                if (!CertStrToNameW(0x10001, dataHandle.AddrOfPinnedObject(), 3, IntPtr.Zero, null, ref nameDataLength, out errorStringPtr))
                {
                    string error = Marshal.PtrToStringUni(errorStringPtr);
                    throw new ArgumentException(error);
                }
                nameData = new byte[nameDataLength];
                if (!CertStrToNameW(0x10001, dataHandle.AddrOfPinnedObject(), 3, IntPtr.Zero, nameData, ref nameDataLength, out errorStringPtr))
                {
                    string error = Marshal.PtrToStringUni(errorStringPtr);
                    throw new ArgumentException(error);
                }
                dataHandle.Free();
                dataHandle = GCHandle.Alloc(nameData, GCHandleType.Pinned);
                CryptoApiBlob nameBlob = new CryptoApiBlob {
                    cbData = (uint)nameData.Length, pbData = dataHandle.AddrOfPinnedObject()
                };
                dataHandle.Free();
                CryptKeyProviderInformation keyProvider = new CryptKeyProviderInformation {
                    pwszContainerName = containerName, dwProvType = 0x18, dwKeySpec = 1
                };
                CryptAlgorithmIdentifier algorithm = new CryptAlgorithmIdentifier {
                    pszObjId = "1.2.840.113549.1.1.13", Parameters = new CryptoApiBlob()
                };
                algorithmPointer = Marshal.AllocHGlobal(Marshal.SizeOf(algorithm));
                Marshal.StructureToPtr(algorithm, algorithmPointer, false);
                certificateContext = CertCreateSelfSignCertificate(providerContext, ref nameBlob, 0, ref keyProvider, algorithmPointer, ref startSystemTime, ref endSystemTime, IntPtr.Zero);
                MarshalHelper.CheckReturnValue(certificateContext != IntPtr.Zero);
                return(new X509Certificate2(certificateContext));
            }
            finally
            {
                if (dataHandle.IsAllocated)
                {
                    dataHandle.Free();
                }
                if (certificateContext != IntPtr.Zero)
                {
                    CertFreeCertificateContext(certificateContext);
                }
                if (cryptKey != IntPtr.Zero)
                {
                    CryptDestroyKey(cryptKey);
                }
                if (providerContext != IntPtr.Zero)
                {
                    CryptReleaseContext(providerContext, 0);
                }
                if (algorithmPointer != IntPtr.Zero)
                {
                    Marshal.DestroyStructure(algorithmPointer, typeof(CryptAlgorithmIdentifier));
                    Marshal.FreeHGlobal(algorithmPointer);
                }
            }
        }
示例#7
0
        /// <summary>
        /// Creates the self sign certificate PFX.
        /// </summary>
        /// <param name="x500">The X500.</param>
        /// <param name="startTime">The start time.</param>
        /// <param name="endTime">The end time.</param>
        /// <param name="password">The password.</param>
        /// <returns></returns>
        /// <exception cref="ArgumentException">
        /// </exception>
        public static byte[] CreateSelfSignCertificatePfx(
            string x500,
            DateTime startTime,
            DateTime endTime,
            SecureString password)
        {
            byte[] pfxData;

            if (x500 == null)
            {
                x500 = "";
            }

#if NETCOREAPP3_1
            SubjectAlternativeNameBuilder sanBuilder = new SubjectAlternativeNameBuilder();
            sanBuilder.AddIpAddress(IPAddress.Loopback);
            sanBuilder.AddIpAddress(IPAddress.IPv6Loopback);
            sanBuilder.AddDnsName("localhost");
            sanBuilder.AddDnsName(Environment.MachineName);

            X500DistinguishedName distinguishedName = new X500DistinguishedName(x500);

            using (RSA rsa = RSA.Create(2048))
            {
                var request = new CertificateRequest(distinguishedName, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);

                request.CertificateExtensions.Add(
                    new X509KeyUsageExtension(X509KeyUsageFlags.DataEncipherment | X509KeyUsageFlags.KeyEncipherment | X509KeyUsageFlags.DigitalSignature, false));


                request.CertificateExtensions.Add(
                    new X509EnhancedKeyUsageExtension(
                        new OidCollection {
                    new Oid("1.3.6.1.5.5.7.3.1")
                }, false));

                request.CertificateExtensions.Add(sanBuilder.Build());

                var certificate = request.CreateSelfSigned(new DateTimeOffset(startTime), new DateTimeOffset(endTime));
                certificate.FriendlyName = "Generated Certificate";

                pfxData = certificate.Export(X509ContentType.Pfx, password);
            }
#else
            SystemTime startSystemTime = ToSystemTime(startTime);
            SystemTime endSystemTime   = ToSystemTime(endTime);
            string     containerName   = Guid.NewGuid().ToString();

            GCHandle dataHandle       = new GCHandle();
            IntPtr   providerContext  = IntPtr.Zero;
            IntPtr   cryptKey         = IntPtr.Zero;
            IntPtr   certContext      = IntPtr.Zero;
            IntPtr   certStore        = IntPtr.Zero;
            IntPtr   storeCertContext = IntPtr.Zero;
            IntPtr   passwordPtr      = IntPtr.Zero;
            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                Check(NativeMethods.CryptAcquireContextW(
                          out providerContext,
                          containerName,
                          null,
                          1,   // PROV_RSA_FULL, 2048 bit type: 1 | (2048<<16)
                          8)); // CRYPT_NEWKEYSET

                Check(NativeMethods.CryptGenKey(
                          providerContext,
                          1, // AT_KEYEXCHANGE
                          1, // CRYPT_EXPORTABLE
                          out cryptKey));

                IntPtr errorStringPtr;
                int    nameDataLength = 0;
                byte[] nameData;

                // errorStringPtr gets a pointer into the middle of the x500 string,
                // so x500 needs to be pinned until after we've copied the value
                // of errorStringPtr.
                dataHandle = GCHandle.Alloc(x500, GCHandleType.Pinned);

                if (!NativeMethods.CertStrToNameW(
                        0x00010001, // X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
                        dataHandle.AddrOfPinnedObject(),
                        3,          // CERT_X500_NAME_STR = 3
                        IntPtr.Zero,
                        null,
                        ref nameDataLength,
                        out errorStringPtr))
                {
                    string error = Marshal.PtrToStringUni(errorStringPtr);
                    throw new ArgumentException(error);
                }

                nameData = new byte[nameDataLength];

                if (!NativeMethods.CertStrToNameW(
                        0x00010001, // X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
                        dataHandle.AddrOfPinnedObject(),
                        3,          // CERT_X500_NAME_STR = 3
                        IntPtr.Zero,
                        nameData,
                        ref nameDataLength,
                        out errorStringPtr))
                {
                    string error = Marshal.PtrToStringUni(errorStringPtr);
                    throw new ArgumentException(error);
                }

                dataHandle.Free();

                dataHandle = GCHandle.Alloc(nameData, GCHandleType.Pinned);
                CryptoApiBlob nameBlob = new CryptoApiBlob(
                    nameData.Length,
                    dataHandle.AddrOfPinnedObject());

                CryptKeyProviderInformation kpi = new CryptKeyProviderInformation();
                kpi.ContainerName = containerName;
                kpi.ProviderType  = 1; // PROV_RSA_FULL
                kpi.KeySpec       = 1; // AT_KEYEXCHANGE

                certContext = NativeMethods.CertCreateSelfSignCertificate(
                    providerContext,
                    ref nameBlob,
                    0,
                    ref kpi,
                    IntPtr.Zero, // default = SHA1RSA
                    ref startSystemTime,
                    ref endSystemTime,
                    IntPtr.Zero);
                Check(certContext != IntPtr.Zero);
                dataHandle.Free();

                certStore = NativeMethods.CertOpenStore(
                    "Memory", // sz_CERT_STORE_PROV_MEMORY
                    0,
                    IntPtr.Zero,
                    0x2000, // CERT_STORE_CREATE_NEW_FLAG
                    IntPtr.Zero);
                Check(certStore != IntPtr.Zero);

                Check(NativeMethods.CertAddCertificateContextToStore(
                          certStore,
                          certContext,
                          1, // CERT_STORE_ADD_NEW
                          out storeCertContext));

                NativeMethods.CertSetCertificateContextProperty(
                    storeCertContext,
                    2, // CERT_KEY_PROV_INFO_PROP_ID
                    0,
                    ref kpi);

                if (password != null)
                {
                    passwordPtr = Marshal.SecureStringToCoTaskMemUnicode(password);
                }

                CryptoApiBlob pfxBlob = new CryptoApiBlob();
                Check(NativeMethods.PFXExportCertStoreEx(
                          certStore,
                          ref pfxBlob,
                          passwordPtr,
                          IntPtr.Zero,
                          7)); // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY

                pfxData      = new byte[pfxBlob.DataLength];
                dataHandle   = GCHandle.Alloc(pfxData, GCHandleType.Pinned);
                pfxBlob.Data = dataHandle.AddrOfPinnedObject();
                Check(NativeMethods.PFXExportCertStoreEx(
                          certStore,
                          ref pfxBlob,
                          passwordPtr,
                          IntPtr.Zero,
                          7)); // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY
                dataHandle.Free();
            }
            finally
            {
                if (passwordPtr != IntPtr.Zero)
                {
                    Marshal.ZeroFreeCoTaskMemUnicode(passwordPtr);
                }

                if (dataHandle.IsAllocated)
                {
                    dataHandle.Free();
                }

                if (certContext != IntPtr.Zero)
                {
                    NativeMethods.CertFreeCertificateContext(certContext);
                }

                if (storeCertContext != IntPtr.Zero)
                {
                    NativeMethods.CertFreeCertificateContext(storeCertContext);
                }

                if (certStore != IntPtr.Zero)
                {
                    NativeMethods.CertCloseStore(certStore, 0);
                }

                if (cryptKey != IntPtr.Zero)
                {
                    NativeMethods.CryptDestroyKey(cryptKey);
                }

                if (providerContext != IntPtr.Zero)
                {
                    NativeMethods.CryptReleaseContext(providerContext, 0);
                    NativeMethods.CryptAcquireContextW(
                        out providerContext,
                        containerName,
                        null,
                        1,     // PROV_RSA_FULL
                        0x10); // CRYPT_DELETEKEYSET
                }
            }
#endif
            return(pfxData);
        }
        internal static byte[] CreateSelfSignCertificatePfx(
            string x500,
            DateTime startTime,
            DateTime endTime,
            SecureString password)
        {
            byte[] pfxData;

            if (x500 == null)
            {
                x500 = "";
            }

            SystemTime startSystemTime = ToSystemTime(startTime);
            SystemTime endSystemTime   = ToSystemTime(endTime);
            string     containerName   = Guid.NewGuid().ToString();

            GCHandle dataHandle       = new GCHandle();
            IntPtr   providerContext  = IntPtr.Zero;
            IntPtr   cryptKey         = IntPtr.Zero;
            IntPtr   certContext      = IntPtr.Zero;
            IntPtr   certStore        = IntPtr.Zero;
            IntPtr   storeCertContext = IntPtr.Zero;
            IntPtr   passwordPtr      = IntPtr.Zero;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                Check(NativeMethods.CryptAcquireContextW(
                          out providerContext,
                          containerName,
                          null,
                          1,   // PROV_RSA_FULL
                          8)); // CRYPT_NEWKEYSET

                Check(NativeMethods.CryptGenKey(
                          providerContext,
                          1,                // AT_KEYEXCHANGE
                          1 | (2048 << 16), // CRYPT_EXPORTABLE | 2048bit
                          out cryptKey));

                IntPtr errorStringPtr;
                int    nameDataLength = 0;
                byte[] nameData;

                // errorStringPtr gets a pointer into the middle of the x500 string,
                // so x500 needs to be pinned until after we've copied the value
                // of errorStringPtr.
                dataHandle = GCHandle.Alloc(x500, GCHandleType.Pinned);

                if (!NativeMethods.CertStrToNameW(
                        0x00010001, // X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
                        dataHandle.AddrOfPinnedObject(),
                        3,          // CERT_X500_NAME_STR = 3
                        IntPtr.Zero,
                        null,
                        ref nameDataLength,
                        out errorStringPtr))
                {
                    string error = Marshal.PtrToStringUni(errorStringPtr);
                    throw new ArgumentException(error);
                }

                nameData = new byte[nameDataLength];

                if (!NativeMethods.CertStrToNameW(
                        0x00010001, // X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
                        dataHandle.AddrOfPinnedObject(),
                        3,          // CERT_X500_NAME_STR = 3
                        IntPtr.Zero,
                        nameData,
                        ref nameDataLength,
                        out errorStringPtr))
                {
                    string error = Marshal.PtrToStringUni(errorStringPtr);
                    throw new ArgumentException(error);
                }

                dataHandle.Free();

                dataHandle = GCHandle.Alloc(nameData, GCHandleType.Pinned);
                CryptoApiBlob nameBlob = new CryptoApiBlob(
                    nameData.Length,
                    dataHandle.AddrOfPinnedObject());

                CryptKeyProviderInformation kpi = new CryptKeyProviderInformation();
                kpi.ContainerName = containerName;
                kpi.ProviderType  = 1; // PROV_RSA_FULL
                kpi.KeySpec       = 1; // AT_KEYEXCHANGE

                certContext = NativeMethods.CertCreateSelfSignCertificate(
                    providerContext,
                    ref nameBlob,
                    0,
                    ref kpi,
                    IntPtr.Zero, // default = SHA1RSA
                    ref startSystemTime,
                    ref endSystemTime,
                    IntPtr.Zero);
                Check(certContext != IntPtr.Zero);
                dataHandle.Free();

                certStore = NativeMethods.CertOpenStore(
                    "Memory", // sz_CERT_STORE_PROV_MEMORY
                    0,
                    IntPtr.Zero,
                    0x2000, // CERT_STORE_CREATE_NEW_FLAG
                    IntPtr.Zero);
                Check(certStore != IntPtr.Zero);

                Check(NativeMethods.CertAddCertificateContextToStore(
                          certStore,
                          certContext,
                          1, // CERT_STORE_ADD_NEW
                          out storeCertContext));

                NativeMethods.CertSetCertificateContextProperty(
                    storeCertContext,
                    2, // CERT_KEY_PROV_INFO_PROP_ID
                    0,
                    ref kpi);

                if (password != null)
                {
                    passwordPtr = Marshal.SecureStringToCoTaskMemUnicode(password);
                }

                CryptoApiBlob pfxBlob = new CryptoApiBlob();
                Check(NativeMethods.PFXExportCertStoreEx(
                          certStore,
                          ref pfxBlob,
                          passwordPtr,
                          IntPtr.Zero,
                          7)); // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY

                pfxData      = new byte[pfxBlob.DataLength];
                dataHandle   = GCHandle.Alloc(pfxData, GCHandleType.Pinned);
                pfxBlob.Data = dataHandle.AddrOfPinnedObject();
                Check(NativeMethods.PFXExportCertStoreEx(
                          certStore,
                          ref pfxBlob,
                          passwordPtr,
                          IntPtr.Zero,
                          7)); // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY
                dataHandle.Free();
            }
            finally
            {
                if (passwordPtr != IntPtr.Zero)
                {
                    Marshal.ZeroFreeCoTaskMemUnicode(passwordPtr);
                }

                if (dataHandle.IsAllocated)
                {
                    dataHandle.Free();
                }

                if (certContext != IntPtr.Zero)
                {
                    NativeMethods.CertFreeCertificateContext(certContext);
                }

                if (storeCertContext != IntPtr.Zero)
                {
                    NativeMethods.CertFreeCertificateContext(storeCertContext);
                }

                if (certStore != IntPtr.Zero)
                {
                    NativeMethods.CertCloseStore(certStore, 0);
                }

                if (cryptKey != IntPtr.Zero)
                {
                    NativeMethods.CryptDestroyKey(cryptKey);
                }

                if (providerContext != IntPtr.Zero)
                {
                    NativeMethods.CryptReleaseContext(providerContext, 0);
                    NativeMethods.CryptAcquireContextW(
                        out providerContext,
                        containerName,
                        null,
                        1,     // PROV_RSA_FULL
                        0x10); // CRYPT_DELETEKEYSET
                }
            }

            return(pfxData);
        }
示例#9
0
        public static byte[] CreateSelfSignCertificatePfx(
            string x500,
            DateTime startTime,
            DateTime endTime,
            SecureString password)
        {
            byte[] pfxData;

            if (x500 == null)
            {
                x500 = "";
            }

            SystemTime startSystemTime = ToSystemTime(startTime);
            SystemTime endSystemTime = ToSystemTime(endTime);
            string containerName = Guid.NewGuid().ToString();

            var dataHandle = new GCHandle();
            var providerContext = IntPtr.Zero;
            var cryptKey = IntPtr.Zero;
            var certContext = IntPtr.Zero;
            var certStore = IntPtr.Zero;
            var storeCertContext = IntPtr.Zero;
            var passwordPtr = IntPtr.Zero;
            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                Check(NativeMethods.CryptAcquireContextW(
                    out providerContext,
                    containerName,
                    null,
                    1, // PROV_RSA_FULL
                    8)); // CRYPT_NEWKEYSET

                Check(NativeMethods.CryptGenKey(
                    providerContext,
                    1, // AT_KEYEXCHANGE
                    1, // CRYPT_EXPORTABLE
                    out cryptKey));

                IntPtr errorStringPtr;
                int nameDataLength = 0;
                byte[] nameData;

                // errorStringPtr gets a pointer into the middle of the x500 string,
                // so x500 needs to be pinned until after we've copied the value
                // of errorStringPtr.
                dataHandle = GCHandle.Alloc(x500, GCHandleType.Pinned);

                if (!NativeMethods.CertStrToNameW(
                    0x00010001, // X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
                    dataHandle.AddrOfPinnedObject(),
                    3, // CERT_X500_NAME_STR = 3
                    IntPtr.Zero,
                    null,
                    ref nameDataLength,
                    out errorStringPtr))
                {
                    string error = Marshal.PtrToStringUni(errorStringPtr);
                    throw new ArgumentException(error);
                }

                nameData = new byte[nameDataLength];

                if (!NativeMethods.CertStrToNameW(
                    0x00010001, // X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
                    dataHandle.AddrOfPinnedObject(),
                    3, // CERT_X500_NAME_STR = 3
                    IntPtr.Zero,
                    nameData,
                    ref nameDataLength,
                    out errorStringPtr))
                {
                    string error = Marshal.PtrToStringUni(errorStringPtr);
                    throw new ArgumentException(error);
                }

                dataHandle.Free();

                dataHandle = GCHandle.Alloc(nameData, GCHandleType.Pinned);
                var nameBlob = new CryptoApiBlob(
                    nameData.Length,
                    dataHandle.AddrOfPinnedObject());

                var kpi = new CryptKeyProviderInformation();
                kpi.ContainerName = containerName;
                kpi.ProviderType = 1; // PROV_RSA_FULL
                kpi.KeySpec = 1; // AT_KEYEXCHANGE

                certContext = NativeMethods.CertCreateSelfSignCertificate(
                    providerContext,
                    ref nameBlob,
                    0,
                    ref kpi,
                    IntPtr.Zero, // default = SHA1RSA
                    ref startSystemTime,
                    ref endSystemTime,
                    IntPtr.Zero);
                Check(certContext != IntPtr.Zero);
                dataHandle.Free();

                certStore = NativeMethods.CertOpenStore(
                    "Memory", // sz_CERT_STORE_PROV_MEMORY
                    0,
                    IntPtr.Zero,
                    0x2000, // CERT_STORE_CREATE_NEW_FLAG
                    IntPtr.Zero);
                Check(certStore != IntPtr.Zero);

                Check(NativeMethods.CertAddCertificateContextToStore(
                    certStore,
                    certContext,
                    1, // CERT_STORE_ADD_NEW
                    out storeCertContext));

                NativeMethods.CertSetCertificateContextProperty(
                    storeCertContext,
                    2, // CERT_KEY_PROV_INFO_PROP_ID
                    0,
                    ref kpi);

                if (password != null)
                {
                    passwordPtr = Marshal.SecureStringToCoTaskMemUnicode(password);
                }

                var pfxBlob = new CryptoApiBlob();
                Check(NativeMethods.PFXExportCertStoreEx(
                    certStore,
                    ref pfxBlob,
                    passwordPtr,
                    IntPtr.Zero,
                    7)); // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY

                pfxData = new byte[pfxBlob.DataLength];
                dataHandle = GCHandle.Alloc(pfxData, GCHandleType.Pinned);
                pfxBlob.Data = dataHandle.AddrOfPinnedObject();
                Check(NativeMethods.PFXExportCertStoreEx(
                    certStore,
                    ref pfxBlob,
                    passwordPtr,
                    IntPtr.Zero,
                    7)); // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY
                dataHandle.Free();
            }
            finally
            {
                if (passwordPtr != IntPtr.Zero)
                {
                    Marshal.ZeroFreeCoTaskMemUnicode(passwordPtr);
                }

                if (dataHandle.IsAllocated)
                {
                    dataHandle.Free();
                }

                if (certContext != IntPtr.Zero)
                {
                    NativeMethods.CertFreeCertificateContext(certContext);
                }

                if (storeCertContext != IntPtr.Zero)
                {
                    NativeMethods.CertFreeCertificateContext(storeCertContext);
                }

                if (certStore != IntPtr.Zero)
                {
                    NativeMethods.CertCloseStore(certStore, 0);
                }

                if (cryptKey != IntPtr.Zero)
                {
                    NativeMethods.CryptDestroyKey(cryptKey);
                }

                if (providerContext != IntPtr.Zero)
                {
                    NativeMethods.CryptReleaseContext(providerContext, 0);
                    NativeMethods.CryptAcquireContextW(
                        out providerContext,
                        containerName,
                        null,
                        1, // PROV_RSA_FULL
                        0x10); // CRYPT_DELETEKEYSET
                }
            }

            return pfxData;
        }
示例#10
0
		private static byte[] ExportCertificate(IntPtr certStore, SecureString password)
		{
			GCHandle dataHandle = new GCHandle();
			IntPtr passwordPtr = IntPtr.Zero;
			if (password != null)
			{
				passwordPtr = Marshal.SecureStringToCoTaskMemUnicode(password);
			}

			try
			{
				byte[] pfxData;
				CryptoApiBlob pfxBlob = new CryptoApiBlob();
				Check(NativeMethods.PFXExportCertStoreEx(
			      		certStore,
			      		ref pfxBlob,
			      		passwordPtr,
			      		IntPtr.Zero,
			      		7)); // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY

				pfxData = new byte[pfxBlob.DataLength];
				dataHandle = GCHandle.Alloc(pfxData, GCHandleType.Pinned);
				pfxBlob.Data = dataHandle.AddrOfPinnedObject();
				Check(NativeMethods.PFXExportCertStoreEx(
			      		certStore,
			      		ref pfxBlob,
			      		passwordPtr,
			      		IntPtr.Zero,
			      		7)); // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY
				
				return pfxData;
			}
			finally
			{
				if (passwordPtr != IntPtr.Zero)
				{
					Marshal.ZeroFreeCoTaskMemUnicode(passwordPtr);
				}

				if (dataHandle.IsAllocated)
				{
					dataHandle.Free();
				}
			}
		}
示例#11
0
 public static extern bool PFXIsPFXBlob(
     ref CryptoApiBlob pfxBlob);
示例#12
0
 public static extern IntPtr PFXImportCertStore(
     ref CryptoApiBlob pfxBlob,
     IntPtr password,
     int flags);
示例#13
0
    /// <summary>
    /// 自己証明書作成のメソッド本体
    ///   rawData が nullで、自己証明書を新規作成
    ///   rawDate を指定すると、既存の自己証明書の更新
    /// </summary>
    /// <param name="rawData">更新時の証明書バイナリーデータ</param>
    /// <param name="x500">組織名(CN="XXXXX")</param>
    /// <param name="startTime">開始日</param>
    /// <param name="endTime">終了日</param>
    /// <param name="insecurePassword">セキュア パスワード</param>
    /// <returns>証明書データ</returns>
    public static byte[] CreateSelfSignCertificatePfx(
        byte[] rawData,
        string x500,
        DateTime startTime,
        DateTime endTime,
        SecureString password)
    {
        byte[] pfxData;

        if (x500 == null)
        {
            x500 = "";
        }

        SystemTime startSystemTime = ToSystemTime(startTime);
        SystemTime endSystemTime = ToSystemTime(endTime);
        string containerName = Guid.NewGuid().ToString();

        GCHandle dataHandle = new GCHandle();
        IntPtr providerContext = IntPtr.Zero;
        IntPtr cryptKey = IntPtr.Zero;
        IntPtr certContext = IntPtr.Zero;
        IntPtr certStore = IntPtr.Zero;
        IntPtr storeCertContext = IntPtr.Zero;
        IntPtr passwordPtr = IntPtr.Zero;
        IntPtr callerFreeProvOrNCryptKey = IntPtr.Zero;

        // コード本体を制約された実行領域 (CER) として指定します。
        RuntimeHelpers.PrepareConstrainedRegions();
        try
        {
            if (password != null)
            {
                // アンマネージ COM タスク アロケーターから割り当てられたメモリ ブロックに、マネージ SecureString オブジェクトの内容をコピーします
                passwordPtr = Marshal.SecureStringToCoTaskMemUnicode(password);
            }

            if (rawData == null)
            {
                // 自己証明書の新規作成用にハンドル(HCRYPTPROV) を取得します(providerContext)

                // cryptographic service provider(CSP)内で キーコンテナに対するハンドル(HCRYPTPROV)を取得します
                Check(NativeMethods.CryptAcquireContextW(
                    out providerContext,
                    containerName,
                    //MS_ENHANCED_PROV,
                    null,
                    PROV_RSA_FULL,
                    CRYPT_NEWKEYSET));

                // ランダムな暗号化用のセッションキーか public/private のキーペアを生成します(HCRYPTKEY)
                Check(NativeMethods.CryptGenKey(
                    providerContext,
                    AT_KEYEXCHANGE,
                    //RSA2048BIT_KEY | CRYPT_EXPORTABLE, // 2048ビットへ変更、標準は1024ビット
                    RSA1024BIT_KEY | CRYPT_EXPORTABLE, // 2048ビットへ変更、標準は1024ビット
                    out cryptKey));
            }
            else
            {
                // 自己証明書の更新用にハンドル(HCRYPTPROV) を取得します(providerContext)

                // 証明書データ(PFX Blob)をインポートします
                CryptoApiBlob certBlob = new CryptoApiBlob();
                certBlob.DataLength = rawData.Length;               // 証明書データをPFX Blobへコピーします
                certBlob.Data = Marshal.AllocHGlobal(certBlob.DataLength);
                Marshal.Copy(rawData, 0, certBlob.Data, rawData.Length);
                Check(NativeMethods.PFXIsPFXBlob(ref certBlob));    // PFX Blobが正常かどうかを確認します
                certStore = NativeMethods.PFXImportCertStore(
                    ref certBlob,
                    passwordPtr,
                    CRYPT_EXPORTABLE | CRYPT_USER_KEYSET);
                Check(certStore != IntPtr.Zero);
                // 証明書を取得します
                certContext = NativeMethods.CertEnumCertificatesInStore(
                    certStore,
                    IntPtr.Zero);
                Check(certContext != IntPtr.Zero);

                // 証明書の private キーを含めて、キーコンテナに対するハンドル(HCRYPTPROV)を取得します
                IntPtr keySpec = IntPtr.Zero;
                Check(NativeMethods.CryptAcquireCertificatePrivateKey(
                    certContext,
                    0,
                    IntPtr.Zero,
                    out providerContext,
                    out keySpec,
                    out callerFreeProvOrNCryptKey));
                // 不要になったハンドルを解放
                Check(NativeMethods.CertCloseStore(certStore, 0));
                Check(NativeMethods.CertFreeCertificateContext(certContext));
                Marshal.FreeHGlobal(certBlob.Data);
                if (keySpec != IntPtr.Zero)
                    Marshal.FreeHGlobal(keySpec);
            }

            IntPtr errorStringPtr;
            int nameDataLength = 0;
            byte[] nameData;

            // errorStringPtr は、 x500 文字列に対するポインターを取得します。
            // この理由で、値を errorStringPtr へコピーするまではピン止めする必要があります
            dataHandle = GCHandle.Alloc(x500, GCHandleType.Pinned);

            // X.500 文字列を エンコードされた証明書名へ変換します
            if (!NativeMethods.CertStrToNameW(
                X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                dataHandle.AddrOfPinnedObject(),
                CERT_X500_NAME_STR,
                IntPtr.Zero,
                null,
                ref nameDataLength,
                out errorStringPtr))
            {
                string error = Marshal.PtrToStringUni(errorStringPtr);
                throw new ArgumentException(error);
            }

            nameData = new byte[nameDataLength];

            if (!NativeMethods.CertStrToNameW(
                X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                dataHandle.AddrOfPinnedObject(),
                CERT_X500_NAME_STR,
                IntPtr.Zero,
                nameData,
                ref nameDataLength,
                out errorStringPtr))
            {
                string error = Marshal.PtrToStringUni(errorStringPtr);
                throw new ArgumentException(error);
            }

            dataHandle.Free();

            dataHandle = GCHandle.Alloc(nameData, GCHandleType.Pinned);
            CryptoApiBlob nameBlob = new CryptoApiBlob(
                nameData.Length,
                dataHandle.AddrOfPinnedObject());

            // 暗号化キー情報
            CryptKeyProviderInformation kpi = new CryptKeyProviderInformation();
            kpi.ContainerName = containerName;
            kpi.ProviderType = PROV_RSA_FULL;
            kpi.KeySpec = AT_KEYEXCHANGE;

            // 自己証明書を作成し、CERT_CONTEXT 構造体のポインター(証明書)を返します。
            // HCRYPTPROV か、NCryptOpenKey を使用した NCRYPT_KEY_HANDLE
            certContext = NativeMethods.CertCreateSelfSignCertificate(
                providerContext,
                ref nameBlob,
                0,
                ref kpi,
                IntPtr.Zero, // default = SHA1RSA
                ref startSystemTime,
                ref endSystemTime,
                IntPtr.Zero);
            Check(certContext != IntPtr.Zero);
            dataHandle.Free();

            // 指定した CSP を使って証明書ストアを開きます
            certStore = NativeMethods.CertOpenStore(
                sz_CERT_STORE_PROV_MEMORY,
                0,
                IntPtr.Zero,
                CERT_STORE_CREATE_NEW_FLAG,
                IntPtr.Zero);
            Check(certStore != IntPtr.Zero);

            // 証明書コンテキストを証明書ストアへ追加します
            Check(NativeMethods.CertAddCertificateContextToStore(
                certStore,
                certContext,
                CERT_STORE_ADD_NEW,
                out storeCertContext));

            // 指定した証明書コンテキストへ拡張プロパティを設定します
            // この場合は暗号化キーです
            NativeMethods.CertSetCertificateContextProperty(
                storeCertContext,
                CERT_KEY_PROV_INFO_PROP_ID,
                0,
                ref kpi);

            CryptoApiBlob pfxBlob = new CryptoApiBlob();
            // 証明書をエクスポートします。参照された証明書ストアから関連付けられた private キーは、存在する場合にです
            // 1度目のエクスポートで、pfxBlob.DataLengthを取得します。
            // 2度目のエクスポートは、pfxBlob.Data を pfxDataにポインター経由で取得します。
            Check(NativeMethods.PFXExportCertStoreEx(
                certStore,
                ref pfxBlob,
                passwordPtr,
                IntPtr.Zero,
                EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY));

            pfxData = new byte[pfxBlob.DataLength];
            dataHandle = GCHandle.Alloc(pfxData, GCHandleType.Pinned);
            pfxBlob.Data = dataHandle.AddrOfPinnedObject();
            Check(NativeMethods.PFXExportCertStoreEx(
                certStore,
                ref pfxBlob,
                passwordPtr,
                IntPtr.Zero,
                EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY));
            dataHandle.Free();
        }
        catch (Exception e)
        {
            throw e;
        }
        finally
        {
            if (passwordPtr != IntPtr.Zero)
            {
                Marshal.ZeroFreeCoTaskMemUnicode(passwordPtr);
            }

            if (dataHandle.IsAllocated)
            {
                dataHandle.Free();
            }

            if (certContext != IntPtr.Zero)
            {
                // 証明書コンテキストを解放します
                NativeMethods.CertFreeCertificateContext(certContext);
            }

            if (storeCertContext != IntPtr.Zero)
            {
                // 証明書ストアコンテキストを解放します
                NativeMethods.CertFreeCertificateContext(storeCertContext);
            }

            if (certStore != IntPtr.Zero)
            {
                // 証明書ストアをクローズします
                NativeMethods.CertCloseStore(certStore, 0);
            }

            if (cryptKey != IntPtr.Zero)
            {
                // 暗号化キーを解放します
                NativeMethods.CryptDestroyKey(cryptKey);
            }

            if (providerContext != IntPtr.Zero)
            {
                // cryptographic service provider(CSP) を解放します
                NativeMethods.CryptReleaseContext(providerContext, 0);
                // 暗号化キーをコンテナから削除します
                NativeMethods.CryptAcquireContextW(
                    out providerContext,
                    containerName,
                    null,
                    PROV_RSA_FULL,
                    CRYPT_DELETEKEYSET);
            }

            if (callerFreeProvOrNCryptKey != IntPtr.Zero)
                Marshal.FreeHGlobal(callerFreeProvOrNCryptKey);
        }

        return pfxData;
    }
        /// <summary>
        /// Create a self-signed certificate.
        /// </summary>
        internal static byte[] CreateSelfSignedCert(
            X500DistinguishedName subjectName, 
            string friendlyName, 
            DateTime startTime, 
            DateTime endTime, 
            SecureString password)
        {
            byte[] pfxData;

            SystemTime startSystemTime = ToSystemTime(startTime);
            SystemTime endSystemTime = ToSystemTime(endTime);
            string containerName = Guid.NewGuid().ToString();

            IntPtr providerContext = IntPtr.Zero;
            IntPtr cryptKey = IntPtr.Zero;
            IntPtr certContext = IntPtr.Zero;
            IntPtr certStore = IntPtr.Zero;
            IntPtr storeCertContext = IntPtr.Zero;
            IntPtr passwordPtr = IntPtr.Zero;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                Check(NativeMethods.CryptAcquireContextW(
                    out providerContext,
                    containerName,
                    null,
                    1, // PROV_RSA_FULL
                    8)); // CRYPT_NEWKEYSET

                Check(NativeMethods.CryptGenKey(
                    providerContext,
                    1, // AT_KEYEXCHANGE
                    1 | (KeySize << 16), // CRYPT_EXPORTABLE
                    out cryptKey));

                unsafe
                {
                    fixed (char* pContainerName = containerName.ToCharArray())
                    {
                        CryptKeyProviderInformation kpi = new CryptKeyProviderInformation();

                        kpi.ContainerName = (IntPtr)pContainerName;
                        kpi.ProviderType = 1; // PROV_RSA_FULL
                        kpi.KeySpec = 1; // AT_KEYEXCHANGE

                        fixed (byte* pSubjectName = &subjectName.RawData[0])
                        {
                            CryptoApiBlob nameBlob = new CryptoApiBlob(
                                subjectName.RawData.Length,
                                (IntPtr)pSubjectName);

                            certContext = NativeMethods.CertCreateSelfSignCertificate(
                                providerContext,
                                ref nameBlob,
                                0,
                                ref kpi,
                                IntPtr.Zero, // default = SHA1RSA
                                ref startSystemTime,
                                ref endSystemTime,
                                IntPtr.Zero);
                            Check(certContext != IntPtr.Zero);
                        }

                        certStore = NativeMethods.CertOpenStore(
                            "Memory", // sz_CERT_STORE_PROV_MEMORY
                            0,
                            IntPtr.Zero,
                            0x2000, // CERT_STORE_CREATE_NEW_FLAG
                            IntPtr.Zero);
                        Check(certStore != IntPtr.Zero);

                        Check(NativeMethods.CertAddCertificateContextToStore(
                            certStore,
                            certContext,
                            1, // CERT_STORE_ADD_NEW
                            out storeCertContext));

                        NativeMethods.CertSetCertificateContextProperty(
                            storeCertContext,
                            2, // CERT_KEY_PROV_INFO_PROP_ID
                            0,
                            (IntPtr)(&kpi));
                    }

                    fixed (char* pFriendlyName = friendlyName.ToCharArray())
                    {
                        var blob = new CryptoApiBlob(
                            friendlyName.Length * sizeof(char),
                            (IntPtr)pFriendlyName);

                        NativeMethods.CertSetCertificateContextProperty(
                            storeCertContext,
                            11, // CERT_FRIENDLY_NAME_PROP_ID
                            0,
                            (IntPtr)(&blob));
                    }

                    if (password != null && password.Length > 0)
                    {
                        passwordPtr = Marshal.SecureStringToCoTaskMemUnicode(password);
                    }

                    CryptoApiBlob pfxBlob = new CryptoApiBlob();
                    Check(NativeMethods.PFXExportCertStoreEx(
                        certStore,
                        ref pfxBlob,
                        passwordPtr,
                        IntPtr.Zero,
                        7)); // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY

                    pfxData = new byte[pfxBlob.DataLength];
                    fixed (byte* pData = pfxData)
                    {
                        pfxBlob.Data = (IntPtr)pData;
                        Check(NativeMethods.PFXExportCertStoreEx(
                            certStore,
                            ref pfxBlob,
                            passwordPtr,
                            IntPtr.Zero,
                            7)); // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY
                    }
                }
            }
            finally
            {
                if (passwordPtr != IntPtr.Zero)
                {
                    Marshal.ZeroFreeCoTaskMemUnicode(passwordPtr);
                }

                if (certContext != IntPtr.Zero)
                {
                    NativeMethods.CertFreeCertificateContext(certContext);
                }

                if (storeCertContext != IntPtr.Zero)
                {
                    NativeMethods.CertFreeCertificateContext(storeCertContext);
                }

                if (certStore != IntPtr.Zero)
                {
                    NativeMethods.CertCloseStore(certStore, 0);
                }

                if (cryptKey != IntPtr.Zero)
                {
                    NativeMethods.CryptDestroyKey(cryptKey);
                }

                if (providerContext != IntPtr.Zero)
                {
                    NativeMethods.CryptReleaseContext(providerContext, 0);
                    NativeMethods.CryptAcquireContextW(
                        out providerContext,
                        containerName,
                        null,
                        1, // PROV_RSA_FULL
                        0x10); // CRYPT_DELETEKEYSET
                }
            }

            return pfxData;
        }
示例#15
0
		private static IntPtr CreateSelfSignedCertificate(IntPtr providerContext, string distinguishedName, DateTime startTime, DateTime endTime, ref CryptKeyProviderInformation kpi)
		{
			SystemTime startSystemTime = ToSystemTime(startTime);
			SystemTime endSystemTime = ToSystemTime(endTime);

			byte[] nameData = GetNameData(distinguishedName);
			GCHandle dataHandle = GCHandle.Alloc(nameData, GCHandleType.Pinned);
			try
			{
				CryptoApiBlob nameBlob = new CryptoApiBlob(nameData.Length, dataHandle.AddrOfPinnedObject());
				IntPtr certContext = NativeMethods.CertCreateSelfSignCertificate(
					providerContext,
					ref nameBlob,
					0,
					ref kpi,
					IntPtr.Zero, // default = SHA1RSA
					ref startSystemTime,
					ref endSystemTime,
					IntPtr.Zero);
				Check(certContext != IntPtr.Zero);
				dataHandle.Free();

				return certContext;
			}
			finally
			{
				if (dataHandle.IsAllocated)
				{
					dataHandle.Free();
				}
			}
		}
示例#16
0
 public static extern bool PFXExportCertStoreEx(
     IntPtr certificateStoreHandle,
     ref CryptoApiBlob pfxBlob,
     IntPtr password,
     IntPtr reserved,
     int flags);
示例#17
0
        /// <summary>建立自签名证书</summary>
        /// <param name="distName"></param>
        /// <param name="startTime"></param>
        /// <param name="endTime"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public static Byte[] CreateSelfSignCertificatePfx(X500DistinguishedName distName, DateTime startTime, DateTime endTime, SecureString password)
        {
            var containerName = Guid.NewGuid().ToString();

            var dataHandle = new GCHandle();
            var providerContext = IntPtr.Zero;
            var cryptKey = IntPtr.Zero;
            var certContext = IntPtr.Zero;
            var certStore = IntPtr.Zero;
            var storeCertContext = IntPtr.Zero;
            var passwordPtr = IntPtr.Zero;
            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                Check(NativeMethods.CryptAcquireContextW(
                    out providerContext,
                    containerName,
                    null,
                    1, // PROV_RSA_FULL
                    8)); // CRYPT_NEWKEYSET

                Check(NativeMethods.CryptGenKey(
                    providerContext,
                    1, // AT_KEYEXCHANGE
                    1, // CRYPT_EXPORTABLE
                    out cryptKey));

                var nameData = distName.RawData;

                dataHandle = GCHandle.Alloc(nameData, GCHandleType.Pinned);
                var nameBlob = new CryptoApiBlob(nameData.Length, dataHandle.AddrOfPinnedObject());

                var kpi = new CryptKeyProviderInformation();
                kpi.ContainerName = containerName;
                kpi.ProviderType = 1; // PROV_RSA_FULL
                kpi.KeySpec = 1; // AT_KEYEXCHANGE

                var startSystemTime = ToSystemTime(startTime);
                var endSystemTime = ToSystemTime(endTime);
                certContext = NativeMethods.CertCreateSelfSignCertificate(
                    providerContext,
                    ref nameBlob,
                    0,
                    ref kpi,
                    IntPtr.Zero, // default = SHA1RSA
                    ref startSystemTime,
                    ref endSystemTime,
                    IntPtr.Zero);
                Check(certContext != IntPtr.Zero);
                dataHandle.Free();

                certStore = NativeMethods.CertOpenStore(
                    "Memory", // sz_CERT_STORE_PROV_MEMORY
                    0,
                    IntPtr.Zero,
                    0x2000, // CERT_STORE_CREATE_NEW_FLAG
                    IntPtr.Zero);
                Check(certStore != IntPtr.Zero);

                Check(NativeMethods.CertAddCertificateContextToStore(
                    certStore,
                    certContext,
                    1, // CERT_STORE_ADD_NEW
                    out storeCertContext));

                NativeMethods.CertSetCertificateContextProperty(
                    storeCertContext,
                    2, // CERT_KEY_PROV_INFO_PROP_ID
                    0,
                    ref kpi);

                if (password != null)
                {
                    passwordPtr = Marshal.SecureStringToCoTaskMemUnicode(password);
                }

                var pfxBlob = new CryptoApiBlob();
                Check(NativeMethods.PFXExportCertStoreEx(
                    certStore,
                    ref pfxBlob,
                    passwordPtr,
                    IntPtr.Zero,
                    7)); // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY

                var pfxData = new Byte[pfxBlob.DataLength];
                dataHandle = GCHandle.Alloc(pfxData, GCHandleType.Pinned);
                pfxBlob.Data = dataHandle.AddrOfPinnedObject();
                Check(NativeMethods.PFXExportCertStoreEx(
                    certStore,
                    ref pfxBlob,
                    passwordPtr,
                    IntPtr.Zero,
                    7)); // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY
                dataHandle.Free();

                return pfxData;
            }
            finally
            {
                if (passwordPtr != IntPtr.Zero) Marshal.ZeroFreeCoTaskMemUnicode(passwordPtr);

                if (dataHandle.IsAllocated) dataHandle.Free();

                if (certContext != IntPtr.Zero) NativeMethods.CertFreeCertificateContext(certContext);

                if (storeCertContext != IntPtr.Zero) NativeMethods.CertFreeCertificateContext(storeCertContext);

                if (certStore != IntPtr.Zero) NativeMethods.CertCloseStore(certStore, 0);

                if (cryptKey != IntPtr.Zero) NativeMethods.CryptDestroyKey(cryptKey);

                if (providerContext != IntPtr.Zero)
                {
                    NativeMethods.CryptReleaseContext(providerContext, 0);
                    NativeMethods.CryptAcquireContextW(
                        out providerContext,
                        containerName,
                        null,
                        1, // PROV_RSA_FULL
                        0x10); // CRYPT_DELETEKEYSET
                }
            }
        }
        public static byte[] CreateSelfSignedPfx(string subject, DateTime startTime, DateTime endTime, SecureString password)
        {
            if (subject == null)
            {
                throw new ArgumentNullException("Subject is null");
            }

            var startSystemTime = ToSystemTime(startTime);
            var endSystemTime   = ToSystemTime(endTime);
            var containerName   = Guid.NewGuid().ToString();

            var dataHandle       = new GCHandle();
            var providerContext  = IntPtr.Zero;
            var cryptKey         = IntPtr.Zero;
            var certContext      = IntPtr.Zero;
            var certStore        = IntPtr.Zero;
            var storeCertContext = IntPtr.Zero;
            var passwordPtr      = IntPtr.Zero;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                Check(NativeMethods.CryptAcquireContextW(out providerContext, containerName, null, ProviderType.RsaAes, 8 /*CRYPT_NEWKEYSET*/));
                Check(NativeMethods.CryptGenKey(providerContext, 1 /*AT_KEYEXCHANGE*/, 0x08000001 /*RSA2048BIT_KEY | CRYPT_EXPORTABLE*/, out cryptKey));

                // errorStringPtr gets a pointer into the middle of the subject string,
                // so subject needs to be pinned until after we've copied the value
                // of errorStringPtr.
                dataHandle = GCHandle.Alloc(subject, GCHandleType.Pinned);
                var nameDataLength = 0;

                if (!NativeMethods.CertStrToNameW(
                        0x00010001, // X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
                        dataHandle.AddrOfPinnedObject(),
                        3,          // CERT_X500_NAME_STR = 3
                        IntPtr.Zero,
                        null,
                        ref nameDataLength,
                        out IntPtr errorStringPtr))
                {
                    var error = Marshal.PtrToStringUni(errorStringPtr);
                    throw new ArgumentException(error);
                }

                var subjectData = new byte[nameDataLength];
                if (!NativeMethods.CertStrToNameW(
                        0x00010001, // X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
                        dataHandle.AddrOfPinnedObject(),
                        3,          // CERT_X500_NAME_STR = 3
                        IntPtr.Zero,
                        subjectData,
                        ref nameDataLength,
                        out errorStringPtr))
                {
                    var error = Marshal.PtrToStringUni(errorStringPtr);
                    throw new ArgumentException(error);
                }

                dataHandle.Free();

                dataHandle = GCHandle.Alloc(subjectData, GCHandleType.Pinned);
                var subjectBlob = new CryptoApiBlob(subjectData.Length, dataHandle.AddrOfPinnedObject());

                var kpi = new CryptKeyProviderInformation
                {
                    ContainerName = containerName,
                    ProviderType  = ProviderType.RsaAes,
                    KeySpec       = 1 // AT_KEYEXCHANGE
                };

                var ai = new CryptAlgorithmIdentifier
                {
                    pszObjId   = "1.2.840.113549.1.1.13", // SHA512RSA
                    Parameters = IntPtr.Zero
                };

                certContext = NativeMethods.CertCreateSelfSignCertificate(providerContext, ref subjectBlob, 0, ref kpi, ref ai, ref startSystemTime, ref endSystemTime, IntPtr.Zero);
                Check(certContext != IntPtr.Zero);
                dataHandle.Free();

                certStore = NativeMethods.CertOpenStore("Memory" /*sz_CERT_STORE_PROV_MEMORY*/, 0, IntPtr.Zero, 0x2000 /*CERT_STORE_CREATE_NEW_FLAG*/, IntPtr.Zero);
                Check(certStore != IntPtr.Zero);

                Check(NativeMethods.CertAddCertificateContextToStore(certStore, certContext, 1, /*CERT_STORE_ADD_NEW*/ out storeCertContext));
                NativeMethods.CertSetCertificateContextProperty(storeCertContext, 2 /* CERT_KEY_PROV_INFO_PROP_ID */, 0, ref kpi);

                if (password != null)
                {
                    passwordPtr = Marshal.SecureStringToCoTaskMemUnicode(password);
                }

                var pfxBlob = new CryptoApiBlob();
                Check(NativeMethods.PFXExportCertStoreEx(certStore, ref pfxBlob, passwordPtr, IntPtr.Zero, 7)); // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY

                var pfxData = new byte[pfxBlob.DataLength];
                dataHandle   = GCHandle.Alloc(pfxData, GCHandleType.Pinned);
                pfxBlob.Data = dataHandle.AddrOfPinnedObject();
                Check(NativeMethods.PFXExportCertStoreEx(certStore, ref pfxBlob, passwordPtr, IntPtr.Zero, 7)); // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY
                dataHandle.Free();

                return(pfxData);
            }
            finally
            {
                if (passwordPtr != IntPtr.Zero)
                {
                    Marshal.ZeroFreeCoTaskMemUnicode(passwordPtr);
                }

                if (dataHandle.IsAllocated)
                {
                    dataHandle.Free();
                }

                if (certContext != IntPtr.Zero)
                {
                    NativeMethods.CertFreeCertificateContext(certContext);
                }

                if (storeCertContext != IntPtr.Zero)
                {
                    NativeMethods.CertFreeCertificateContext(storeCertContext);
                }

                if (certStore != IntPtr.Zero)
                {
                    NativeMethods.CertCloseStore(certStore, 0);
                }

                if (cryptKey != IntPtr.Zero)
                {
                    NativeMethods.CryptDestroyKey(cryptKey);
                }

                if (providerContext != IntPtr.Zero)
                {
                    NativeMethods.CryptReleaseContext(providerContext, 0);
                    NativeMethods.CryptAcquireContextW(
                        out providerContext,
                        containerName,
                        null,
                        ProviderType.RsaAes,
                        0x10); // CRYPT_DELETEKEYSET
                }
            }
        }
示例#19
0
        /// <summary>
        /// Create a self-signed certificate.
        /// </summary>
        internal static byte[] CreateSelfSignedCert(
            X500DistinguishedName subjectName,
            string friendlyName,
            DateTime startTime,
            DateTime endTime,
            SecureString password)
        {
            byte[] pfxData;

            SystemTime startSystemTime = ToSystemTime(startTime);
            SystemTime endSystemTime   = ToSystemTime(endTime);
            string     containerName   = Guid.NewGuid().ToString();

            IntPtr providerContext  = IntPtr.Zero;
            IntPtr cryptKey         = IntPtr.Zero;
            IntPtr certContext      = IntPtr.Zero;
            IntPtr certStore        = IntPtr.Zero;
            IntPtr storeCertContext = IntPtr.Zero;
            IntPtr passwordPtr      = IntPtr.Zero;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                Check(NativeMethods.CryptAcquireContextW(
                          out providerContext,
                          containerName,
                          null,
                          1,   // PROV_RSA_FULL
                          8)); // CRYPT_NEWKEYSET

                Check(NativeMethods.CryptGenKey(
                          providerContext,
                          1,                   // AT_KEYEXCHANGE
                          1 | (KeySize << 16), // CRYPT_EXPORTABLE
                          out cryptKey));

                unsafe
                {
                    fixed(char *pContainerName = containerName.ToCharArray())
                    {
                        CryptKeyProviderInformation kpi = new CryptKeyProviderInformation();

                        kpi.ContainerName = (IntPtr)pContainerName;
                        kpi.ProviderType  = 1; // PROV_RSA_FULL
                        kpi.KeySpec       = 1; // AT_KEYEXCHANGE

                        fixed(byte *pSubjectName = &subjectName.RawData[0])
                        {
                            CryptoApiBlob nameBlob = new CryptoApiBlob(
                                subjectName.RawData.Length,
                                (IntPtr)pSubjectName);

                            certContext = NativeMethods.CertCreateSelfSignCertificate(
                                providerContext,
                                ref nameBlob,
                                0,
                                ref kpi,
                                IntPtr.Zero, // default = SHA1RSA
                                ref startSystemTime,
                                ref endSystemTime,
                                IntPtr.Zero);
                            Check(certContext != IntPtr.Zero);
                        }

                        certStore = NativeMethods.CertOpenStore(
                            "Memory", // sz_CERT_STORE_PROV_MEMORY
                            0,
                            IntPtr.Zero,
                            0x2000, // CERT_STORE_CREATE_NEW_FLAG
                            IntPtr.Zero);
                        Check(certStore != IntPtr.Zero);

                        Check(NativeMethods.CertAddCertificateContextToStore(
                                  certStore,
                                  certContext,
                                  1, // CERT_STORE_ADD_NEW
                                  out storeCertContext));

                        NativeMethods.CertSetCertificateContextProperty(
                            storeCertContext,
                            2, // CERT_KEY_PROV_INFO_PROP_ID
                            0,
                            (IntPtr)(&kpi));
                    }

                    fixed(char *pFriendlyName = friendlyName.ToCharArray())
                    {
                        var blob = new CryptoApiBlob(
                            friendlyName.Length * sizeof(char),
                            (IntPtr)pFriendlyName);

                        NativeMethods.CertSetCertificateContextProperty(
                            storeCertContext,
                            11, // CERT_FRIENDLY_NAME_PROP_ID
                            0,
                            (IntPtr)(&blob));
                    }

                    if (password != null && password.Length > 0)
                    {
                        passwordPtr = Marshal.SecureStringToCoTaskMemUnicode(password);
                    }

                    CryptoApiBlob pfxBlob = new CryptoApiBlob();

                    Check(NativeMethods.PFXExportCertStoreEx(
                              certStore,
                              ref pfxBlob,
                              passwordPtr,
                              IntPtr.Zero,
                              7)); // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY

                    pfxData = new byte[pfxBlob.DataLength];
                    fixed(byte *pData = pfxData)
                    {
                        pfxBlob.Data = (IntPtr)pData;
                        Check(NativeMethods.PFXExportCertStoreEx(
                                  certStore,
                                  ref pfxBlob,
                                  passwordPtr,
                                  IntPtr.Zero,
                                  7)); // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY
                    }
                }
            }
            finally
            {
                if (passwordPtr != IntPtr.Zero)
                {
                    Marshal.ZeroFreeCoTaskMemUnicode(passwordPtr);
                }

                if (certContext != IntPtr.Zero)
                {
                    NativeMethods.CertFreeCertificateContext(certContext);
                }

                if (storeCertContext != IntPtr.Zero)
                {
                    NativeMethods.CertFreeCertificateContext(storeCertContext);
                }

                if (certStore != IntPtr.Zero)
                {
                    NativeMethods.CertCloseStore(certStore, 0);
                }

                if (cryptKey != IntPtr.Zero)
                {
                    NativeMethods.CryptDestroyKey(cryptKey);
                }

                if (providerContext != IntPtr.Zero)
                {
                    NativeMethods.CryptReleaseContext(providerContext, 0);
                    NativeMethods.CryptAcquireContextW(
                        out providerContext,
                        containerName,
                        null,
                        1,     // PROV_RSA_FULL
                        0x10); // CRYPT_DELETEKEYSET
                }
            }

            return(pfxData);
        }
 public static extern bool PFXExportCertStoreEx(
     IntPtr certificateStoreHandle,
     ref CryptoApiBlob pfxBlob,
     IntPtr password,
     IntPtr reserved,
     int flags);
        public static X509Certificate2 GenerateSelfSignedCertificate(string issuerDN, DateTime?startTime = null, DateTime?endTime = null)
        {
            if (issuerDN == null)
            {
                issuerDN = String.Empty;
            }
            var startSystemTime = default(SystemTime);

            if (startTime == null || (DateTime)startTime < DateTime.FromFileTimeUtc(0))
            {
                startTime       = DateTime.FromFileTimeUtc(0);
                startSystemTime = SystemTime.Create((DateTime)startTime);
            }
            if (endTime == null)
            {
                endTime = DateTime.MaxValue;
            }
            var    endSystemTime      = SystemTime.Create((DateTime)endTime);
            string containerName      = Guid.NewGuid().ToString();
            IntPtr providerContext    = IntPtr.Zero;
            IntPtr cryptKey           = IntPtr.Zero;
            IntPtr certificateContext = IntPtr.Zero;
            IntPtr algorithmPointer   = IntPtr.Zero;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                providerContext = Externs.CryptAcquireContextW(containerName, null, 1, 0x8);
                cryptKey        = Externs.CryptGenKey(providerContext, 1, 0x8000001);
                CryptoApiBlob    nameBlob    = CryptoApiBlob.Create(issuerDN);
                CryptKeyProvInfo keyProvider = new CryptKeyProvInfo
                {
                    pwszContainerName = containerName,
                    dwProvType        = 1,
                    dwKeySpec         = 1
                };
                CryptAlgorithmIdentifier algorithm = new CryptAlgorithmIdentifier
                {
                    pszObjId   = "1.2.840.113549.1.1.13",
                    Parameters = new CryptoApiBlob()
                };
                algorithmPointer = Marshal.AllocHGlobal(Marshal.SizeOf(algorithm));
                Marshal.StructureToPtr(algorithm, algorithmPointer, false);
                certificateContext = Externs.CertCreateSelfSignCertificate(providerContext, nameBlob, 0, keyProvider, algorithmPointer,
                                                                           startSystemTime, endSystemTime, IntPtr.Zero);
                return(new X509Certificate2(certificateContext));
            }
            finally
            {
                if (certificateContext != IntPtr.Zero)
                {
                    Externs.CertFreeCertificateContext(certificateContext);
                }
                if (cryptKey != IntPtr.Zero)
                {
                    Externs.CryptDestroyKey(cryptKey);
                }
                if (providerContext != IntPtr.Zero)
                {
                    Externs.CryptReleaseContext(providerContext, 0);
                }
                if (algorithmPointer != IntPtr.Zero)
                {
                    Marshal.DestroyStructure(algorithmPointer, typeof(CryptAlgorithmIdentifier));
                    Marshal.FreeHGlobal(algorithmPointer);
                }
            }
        }