mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-06-01 21:38:27 +01:00
rework result factory
This commit is contained in:
@@ -1,244 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Net;
|
||||
using System;
|
||||
@@ -8,14 +7,13 @@ using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using Emby.Common.Implementations.Networking;
|
||||
|
||||
namespace MediaBrowser.ServerApplication.Networking
|
||||
{
|
||||
/// <summary>
|
||||
/// Class NetUtils
|
||||
/// </summary>
|
||||
public class NetworkManager : BaseNetworkManager, INetworkManager
|
||||
public class NetworkManager : Server.Startup.Common.Networking.NetworkManager
|
||||
{
|
||||
public NetworkManager(ILogger logger)
|
||||
: base(logger)
|
||||
@@ -160,16 +158,6 @@ namespace MediaBrowser.ServerApplication.Networking
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a self signed certificate at the locatation specified by <paramref name="certificatePath"/>.
|
||||
/// </summary>
|
||||
/// <param name="certificatePath">The path to generate the certificate.</param>
|
||||
/// <param name="hostname">The common name for the certificate.</param>
|
||||
public void GenerateSelfSignedSslCertificate(string certificatePath, string hostname)
|
||||
{
|
||||
CertificateGenerator.CreateSelfSignCertificatePfx(certificatePath, hostname, Logger);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the network prefix.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user