| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 | 
							- using MediaBrowser.Model.Logging;
 
- using System;
 
- using System.IO;
 
- using System.Runtime.CompilerServices;
 
- using System.Runtime.InteropServices;
 
- namespace MediaBrowser.ServerApplication.Networking
 
- {
 
-         // Copied from: http://blogs.msdn.com/b/dcook/archive/2014/05/16/9143036.aspx
 
-     // In case anybody is interested, source code is attached and is free for use by anybody as long as you don't hold me or Microsoft liable for it -- 
 
-     // I have no idea whether this is actually the right or best way to do this. Give it the X500 distinguished name, validity start and end dates, 
 
-     // and an optional password for encrypting the key data, and it will give you the PFX file data. Let me know if you find any bugs or have any suggestions.
 
-     internal class CertificateGenerator
 
-     {
 
-         internal static void CreateSelfSignCertificatePfx(
 
-             string fileName,
 
-             string hostname,
 
-             ILogger logger)
 
-         {
 
-             if (string.IsNullOrWhiteSpace(fileName))
 
-             {
 
-                 throw new ArgumentNullException("fileName");
 
-             }
 
-             string x500 = string.Format("CN={0}", hostname);
 
-             DateTime startTime = DateTime.Now.AddDays(-2);
 
-             DateTime endTime = DateTime.Now.AddYears(10);
 
-             byte[] pfxData = CreateSelfSignCertificatePfx(
 
-                 x500,
 
-                 startTime,
 
-                 endTime);
 
-             File.WriteAllBytes(fileName, pfxData);
 
-         }
 
-         private static byte[] CreateSelfSignCertificatePfx(
 
-             string x500,
 
-             DateTime startTime,
 
-             DateTime endTime)
 
-         {
 
-             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 2048 bit key
 
-                     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
 
-                 CryptAlgorithmIdentifier sha256Identifier = new CryptAlgorithmIdentifier();
 
-                 sha256Identifier.pszObjId = "1.2.840.113549.1.1.11";
 
-                 certContext = NativeMethods.CertCreateSelfSignCertificate(
 
-                     providerContext,
 
-                     ref nameBlob,
 
-                     0,
 
-                     ref kpi,
 
-                     ref sha256Identifier,
 
-                     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);
 
-                 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;
 
-         }
 
-         private static SystemTime ToSystemTime(DateTime dateTime)
 
-         {
 
-             long fileTime = dateTime.ToFileTime();
 
-             SystemTime systemTime;
 
-             Check(NativeMethods.FileTimeToSystemTime(ref fileTime, out systemTime));
 
-             return systemTime;
 
-         }
 
-         private static void Check(bool nativeCallSucceeded)
 
-         {
 
-             if (!nativeCallSucceeded)
 
-             {
 
-                 int error = Marshal.GetHRForLastWin32Error();
 
-                 Marshal.ThrowExceptionForHR(error);
 
-             }
 
-         }
 
-     }
 
- }
 
 
  |