Compare commits
No commits in common. "f1cd0e27b72b02c3ae257fb4a22379b5d4086663" and "19e1e9fa465a2f573d466de22299c7f29649e0c4" have entirely different histories.
f1cd0e27b7
...
19e1e9fa46
10
.gitignore
vendored
10
.gitignore
vendored
@ -13,13 +13,3 @@
|
|||||||
/Sophia.Net.Aesthetics.Windows95/bin/Debug/net8.0-windows
|
/Sophia.Net.Aesthetics.Windows95/bin/Debug/net8.0-windows
|
||||||
/Sophia.Net.Aesthetics.VisualStudio6/bin/Debug/net8.0-windows
|
/Sophia.Net.Aesthetics.VisualStudio6/bin/Debug/net8.0-windows
|
||||||
/Sophia.Net.Aesthetics.Office2000/bin/Debug/net8.0-windows
|
/Sophia.Net.Aesthetics.Office2000/bin/Debug/net8.0-windows
|
||||||
*.metadata.v9.bin
|
|
||||||
*.projects.v9.bin
|
|
||||||
*.strings.v9.bin
|
|
||||||
/Sophia.Net.DRM/.vs/Sophia.Net.DRM/FileContentIndex
|
|
||||||
/Sophia.Net.DRM/.vs/Sophia.Net.DRM/v17
|
|
||||||
/Sophia.Net.DRM/.vs/Sophia.Net.DRM/CopilotIndices/17.14.1431.25910
|
|
||||||
/Sophia.Net.DRM/obj/Debug/net8.0
|
|
||||||
/Sophia.Net.DRM/obj
|
|
||||||
*.deps.json
|
|
||||||
/Sophia.Net.DRM/.vs/Sophia.Net.DRM/DesignTimeBuild
|
|
||||||
|
|||||||
@ -1,13 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.2" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
|
||||||
# Visual Studio Version 17
|
|
||||||
VisualStudioVersion = 17.14.36705.20 d17.14
|
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sophia.Net.DRM", "Sophia.Net.DRM.csproj", "{30741C45-1A9C-4151-883F-B11965EE376A}"
|
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sophia.Net.DRM.Tool", "..\Sophia.Net.DRM.Tool\Sophia.Net.DRM.Tool.csproj", "{B9D739C2-128B-42E0-8079-406105FB2C67}"
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug|Any CPU = Debug|Any CPU
|
|
||||||
Release|Any CPU = Release|Any CPU
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{30741C45-1A9C-4151-883F-B11965EE376A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{30741C45-1A9C-4151-883F-B11965EE376A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{30741C45-1A9C-4151-883F-B11965EE376A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{30741C45-1A9C-4151-883F-B11965EE376A}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{B9D739C2-128B-42E0-8079-406105FB2C67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{B9D739C2-128B-42E0-8079-406105FB2C67}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{B9D739C2-128B-42E0-8079-406105FB2C67}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{B9D739C2-128B-42E0-8079-406105FB2C67}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
|
||||||
SolutionGuid = {43A39C7F-8F28-4007-A6F1-81F50765BEF0}
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
||||||
@ -1,350 +0,0 @@
|
|||||||
using System.Text;
|
|
||||||
using Org.BouncyCastle.Asn1;
|
|
||||||
using Org.BouncyCastle.Crypto.Prng;
|
|
||||||
using Org.BouncyCastle.Math;
|
|
||||||
using Org.BouncyCastle.Security;
|
|
||||||
using Org.BouncyCastle.Utilities;
|
|
||||||
using Org.BouncyCastle.X509;
|
|
||||||
using Org.BouncyCastle.Asn1.X509;
|
|
||||||
using Org.BouncyCastle.Crypto;
|
|
||||||
using Org.BouncyCastle.Crypto.Digests;
|
|
||||||
using Org.BouncyCastle.Crypto.Generators;
|
|
||||||
using Org.BouncyCastle.Crypto.Operators;
|
|
||||||
using Org.BouncyCastle.Crypto.Signers;
|
|
||||||
using Org.BouncyCastle.OpenSsl;
|
|
||||||
using Org.BouncyCastle.Pkcs;
|
|
||||||
using Org.BouncyCastle.X509.Extension;
|
|
||||||
using X509Certificate = Org.BouncyCastle.X509.X509Certificate;
|
|
||||||
|
|
||||||
namespace Sophia.Net.DRM
|
|
||||||
{
|
|
||||||
public static class SophiaNetDrmApi
|
|
||||||
{
|
|
||||||
|
|
||||||
public static X509Certificate CreateSelfSignedCertificate(string commonName, AsymmetricCipherKeyPair keyPair, string sophiaNetExtension = null, bool addSophiaNetPurpose = false)
|
|
||||||
{
|
|
||||||
CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
|
|
||||||
SecureRandom random = new SecureRandom(randomGenerator);
|
|
||||||
|
|
||||||
//When acting as a certificate authority, use a proper serial number here - as an argument to this function!
|
|
||||||
BigInteger serial = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);
|
|
||||||
|
|
||||||
X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator();
|
|
||||||
certificateGenerator.SetSerialNumber(serial);
|
|
||||||
|
|
||||||
X509Name subjectDn = new X509Name(String.Format("CN={0}", commonName));
|
|
||||||
X509Name issuerDn = subjectDn;
|
|
||||||
certificateGenerator.SetSubjectDN(subjectDn);
|
|
||||||
certificateGenerator.SetIssuerDN(issuerDn);
|
|
||||||
certificateGenerator.SetPublicKey(keyPair.Public);
|
|
||||||
|
|
||||||
DateTime notBefore = DateTime.Now.Date;
|
|
||||||
DateTime notAfter = notBefore.AddYears(100);
|
|
||||||
certificateGenerator.SetNotBefore(notBefore);
|
|
||||||
certificateGenerator.SetNotAfter(notAfter);
|
|
||||||
|
|
||||||
certificateGenerator.AddExtension(X509Extensions.BasicConstraints.Id, true, new BasicConstraints(false));
|
|
||||||
|
|
||||||
|
|
||||||
AsymmetricCipherKeyPair subjectKeyPair = keyPair;
|
|
||||||
AsymmetricCipherKeyPair issuerKeyPair = subjectKeyPair;
|
|
||||||
|
|
||||||
SubjectKeyIdentifier subjectKeyIdentifier = X509ExtensionUtilities.CreateSubjectKeyIdentifier(keyPair.Public);
|
|
||||||
certificateGenerator.AddExtension(X509Extensions.SubjectKeyIdentifier.Id, false, subjectKeyIdentifier);
|
|
||||||
|
|
||||||
AuthorityKeyIdentifier authorityKeyIdentifier = X509ExtensionUtilities.CreateAuthorityKeyIdentifier(issuerKeyPair.Public);
|
|
||||||
certificateGenerator.AddExtension(X509Extensions.AuthorityKeyIdentifier.Id, false, authorityKeyIdentifier);
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(sophiaNetExtension))
|
|
||||||
{
|
|
||||||
DerObjectIdentifier derObjectIdentifier = new DerObjectIdentifier("1.3.6.1.3.545127833961986897372532.1");
|
|
||||||
certificateGenerator.AddExtension(derObjectIdentifier, false, System.Text.Encoding.UTF8.GetBytes("sophia.net self-signed certificate"));
|
|
||||||
}
|
|
||||||
|
|
||||||
List<DerObjectIdentifier> usageList = new List<DerObjectIdentifier>();
|
|
||||||
usageList.Add(KeyPurposeID.id_kp_serverAuth);
|
|
||||||
usageList.Add(KeyPurposeID.id_kp_codeSigning);
|
|
||||||
if (addSophiaNetPurpose)
|
|
||||||
{
|
|
||||||
DerObjectIdentifier doi = new DerObjectIdentifier("1.3.6.1.3.545127833961986897372532.2");
|
|
||||||
usageList.Add(doi);
|
|
||||||
}
|
|
||||||
|
|
||||||
certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage.Id, false, new ExtendedKeyUsage(usageList.ToArray()));
|
|
||||||
|
|
||||||
const string signatureAlgorithm = "SHA256WithRSA";
|
|
||||||
Asn1SignatureFactory asn1SignatureFactory = new Asn1SignatureFactory(signatureAlgorithm, issuerKeyPair.Private, random);
|
|
||||||
X509Certificate x509Certificate = certificateGenerator.Generate(asn1SignatureFactory);
|
|
||||||
return x509Certificate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AsymmetricCipherKeyPair GenerateKeyPair(int strength = 9216, SecureRandom random = null)
|
|
||||||
{
|
|
||||||
if (random == null)
|
|
||||||
{
|
|
||||||
CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
|
|
||||||
random = new SecureRandom(randomGenerator);
|
|
||||||
}
|
|
||||||
KeyGenerationParameters keyGenerationParameters = new KeyGenerationParameters(random, strength);
|
|
||||||
|
|
||||||
RsaKeyPairGenerator rsaKeyPairGenerator = new RsaKeyPairGenerator();
|
|
||||||
rsaKeyPairGenerator.Init(keyGenerationParameters);
|
|
||||||
return rsaKeyPairGenerator.GenerateKeyPair();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] ExportPrivateKey(AsymmetricCipherKeyPair keypair)
|
|
||||||
{
|
|
||||||
MemoryStream memoryStream = new MemoryStream();
|
|
||||||
StreamWriter streamWriter = new StreamWriter(memoryStream);
|
|
||||||
PemWriter pemWriter = new PemWriter(streamWriter);
|
|
||||||
pemWriter.WriteObject(keypair.Private);
|
|
||||||
streamWriter.Flush();
|
|
||||||
memoryStream.Flush();
|
|
||||||
return memoryStream.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] ExportPublicKey(AsymmetricCipherKeyPair keypair)
|
|
||||||
{
|
|
||||||
MemoryStream memoryStream = new MemoryStream();
|
|
||||||
StreamWriter streamWriter = new StreamWriter(memoryStream);
|
|
||||||
PemWriter pemWriter = new PemWriter(streamWriter);
|
|
||||||
pemWriter.WriteObject(keypair.Public);
|
|
||||||
streamWriter.Flush();
|
|
||||||
memoryStream.Flush();
|
|
||||||
return memoryStream.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AsymmetricCipherKeyPair ImportKeyPairFromPrivateKey(byte[] privateBytes)
|
|
||||||
{
|
|
||||||
MemoryStream memoryStream = new MemoryStream(privateBytes);
|
|
||||||
StreamReader streamReader = new StreamReader(memoryStream);
|
|
||||||
PemReader pemReader = new PemReader(streamReader);
|
|
||||||
object privateKey = pemReader.ReadObject();
|
|
||||||
|
|
||||||
AsymmetricCipherKeyPair result = privateKey as AsymmetricCipherKeyPair;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] ExportCertificate(X509Certificate certificate)
|
|
||||||
{
|
|
||||||
return certificate.GetEncoded();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] ExportCertificateAsPkcs12(AsymmetricKeyParameter privateKey, string password, params X509Certificate[] certificate)
|
|
||||||
{
|
|
||||||
CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
|
|
||||||
SecureRandom random = new SecureRandom(randomGenerator);
|
|
||||||
|
|
||||||
Pkcs12StoreBuilder builder = new Pkcs12StoreBuilder();
|
|
||||||
Pkcs12Store store = builder.Build();
|
|
||||||
|
|
||||||
string[] friendlyNames = new string[certificate.Length];
|
|
||||||
X509CertificateEntry[] certificateEntries = new X509CertificateEntry[certificate.Length];
|
|
||||||
for (int i = 0; i < certificate.Length; i++)
|
|
||||||
{
|
|
||||||
friendlyNames[i] = certificate[i].SubjectDN.ToString();
|
|
||||||
certificateEntries[i] = new X509CertificateEntry(certificate[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
store.SetCertificateEntry(friendlyNames[0], certificateEntries[0]);
|
|
||||||
store.SetKeyEntry(friendlyNames[0], new AsymmetricKeyEntry(privateKey), certificateEntries);
|
|
||||||
|
|
||||||
MemoryStream ms = new MemoryStream();
|
|
||||||
store.Save(ms, password.ToCharArray(), random);
|
|
||||||
return ms.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static X509Certificate CreateRootCertificate(string commonName, AsymmetricCipherKeyPair keyPair)
|
|
||||||
{
|
|
||||||
CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
|
|
||||||
SecureRandom random = new SecureRandom(randomGenerator);
|
|
||||||
|
|
||||||
//When issuing child certificates, use a proper serial number here - as an argument to this function!
|
|
||||||
BigInteger serial = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);
|
|
||||||
|
|
||||||
X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator();
|
|
||||||
certificateGenerator.SetSerialNumber(serial);
|
|
||||||
|
|
||||||
X509Name subjectDn = new X509Name(String.Format("CN={0}", commonName));
|
|
||||||
X509Name issuerDn = subjectDn;
|
|
||||||
certificateGenerator.SetSubjectDN(subjectDn);
|
|
||||||
certificateGenerator.SetIssuerDN(issuerDn);
|
|
||||||
certificateGenerator.SetPublicKey(keyPair.Public);
|
|
||||||
|
|
||||||
DateTime notBefore = DateTime.Now.Date;
|
|
||||||
DateTime notAfter = notBefore.AddYears(100);
|
|
||||||
certificateGenerator.SetNotBefore(notBefore);
|
|
||||||
certificateGenerator.SetNotAfter(notAfter);
|
|
||||||
|
|
||||||
//BasicConstraints basicConstraints = new BasicConstraints(true);
|
|
||||||
//certificateGenerator.AddExtension(X509Extensions.BasicConstraints.Id, true, new BasicConstraints(true));
|
|
||||||
certificateGenerator.AddExtension(X509Extensions.BasicConstraints.Id, true, new BasicConstraints(2));
|
|
||||||
|
|
||||||
AsymmetricCipherKeyPair subjectKeyPair = keyPair;
|
|
||||||
AsymmetricCipherKeyPair issuerKeyPair = subjectKeyPair;
|
|
||||||
|
|
||||||
SubjectKeyIdentifier subjectKeyIdentifier = X509ExtensionUtilities.CreateSubjectKeyIdentifier(keyPair.Public);
|
|
||||||
certificateGenerator.AddExtension(X509Extensions.SubjectKeyIdentifier.Id, false, subjectKeyIdentifier);
|
|
||||||
|
|
||||||
AuthorityKeyIdentifier authorityKeyIdentifier = X509ExtensionUtilities.CreateAuthorityKeyIdentifier(issuerKeyPair.Public);
|
|
||||||
certificateGenerator.AddExtension(X509Extensions.AuthorityKeyIdentifier.Id, false, authorityKeyIdentifier);
|
|
||||||
|
|
||||||
const string signatureAlgorithm = "SHA256WithRSA";
|
|
||||||
Asn1SignatureFactory asn1SignatureFactory = new Asn1SignatureFactory(signatureAlgorithm, issuerKeyPair.Private, random);
|
|
||||||
X509Certificate x509Certificate = certificateGenerator.Generate(asn1SignatureFactory);
|
|
||||||
return x509Certificate;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static X509Certificate CreateChildCertificate(string commonName, X509Certificate issuerCert, AsymmetricCipherKeyPair issuerPrivateKey, AsymmetricKeyParameter childPublicKey, long serialNumber, string sophiaNetExtensionValue)
|
|
||||||
{
|
|
||||||
return CreateChildCertificate(commonName, issuerCert, issuerPrivateKey, childPublicKey, serialNumber, Encoding.UTF8.GetBytes(sophiaNetExtensionValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static X509Certificate CreateChildCertificate(string commonName, X509Certificate issuerCert, AsymmetricCipherKeyPair issuerPrivateKey, AsymmetricKeyParameter childPublicKey, long serialNumber, SophiaNetEntitlementCollection entitlements)
|
|
||||||
{
|
|
||||||
byte[] serialize = entitlements.Serialize();
|
|
||||||
return CreateChildCertificate(commonName, issuerCert, issuerPrivateKey, childPublicKey, serialNumber, serialize);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static X509Certificate CreateChildCertificate(string commonName, X509Certificate issuerCert, AsymmetricCipherKeyPair issuerPrivateKey, AsymmetricKeyParameter childPublicKey, long serialNumber, byte[] sophiaNetExtensionValue)
|
|
||||||
{
|
|
||||||
CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
|
|
||||||
SecureRandom random = new SecureRandom(randomGenerator);
|
|
||||||
|
|
||||||
BigInteger serial = BigInteger.ValueOf(serialNumber);
|
|
||||||
|
|
||||||
X509Name subjectDn = new X509Name(String.Format("CN={0}", commonName));
|
|
||||||
|
|
||||||
DateTime notBefore = DateTime.Now.Date;
|
|
||||||
DateTime notAfter = issuerCert.NotAfter;
|
|
||||||
|
|
||||||
DerObjectIdentifier sophiaNetExtensionId = new DerObjectIdentifier("1.3.6.1.3.545127833961986897372532.1");
|
|
||||||
|
|
||||||
X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator();
|
|
||||||
certificateGenerator.SetSerialNumber(serial);
|
|
||||||
certificateGenerator.SetSubjectDN(subjectDn);
|
|
||||||
certificateGenerator.SetIssuerDN(issuerCert.SubjectDN);
|
|
||||||
certificateGenerator.SetPublicKey(childPublicKey);
|
|
||||||
certificateGenerator.SetNotBefore(notBefore);
|
|
||||||
certificateGenerator.SetNotAfter(notAfter);
|
|
||||||
certificateGenerator.AddExtension(X509Extensions.BasicConstraints.Id, true, new BasicConstraints(false));
|
|
||||||
certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage.Id, false, new ExtendedKeyUsage(KeyPurposeID.id_kp_clientAuth));
|
|
||||||
certificateGenerator.AddExtension(sophiaNetExtensionId, false, sophiaNetExtensionValue);
|
|
||||||
|
|
||||||
const string signatureAlgorithm = "SHA256WithRSA";
|
|
||||||
Asn1SignatureFactory asn1SignatureFactory = new Asn1SignatureFactory(signatureAlgorithm, issuerPrivateKey.Private, random);
|
|
||||||
X509Certificate x509Certificate = certificateGenerator.Generate(asn1SignatureFactory);
|
|
||||||
return x509Certificate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static X509Certificate ImportCertificate(byte[] encoded)
|
|
||||||
{
|
|
||||||
X509Certificate result = new X509Certificate(encoded);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool ValidateCertificateChain(X509Certificate child, X509Certificate issuer)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
child.Verify(issuer.GetPublicKey());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static X509Crl CreateCertificateRevocationList(X509Certificate issuer, AsymmetricCipherKeyPair issuerPrivateKey, params long[] revokedSerials)
|
|
||||||
{
|
|
||||||
CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
|
|
||||||
SecureRandom random = new SecureRandom(randomGenerator);
|
|
||||||
|
|
||||||
long notAfterSeconds = issuer.NotAfter.Ticks / TimeSpan.TicksPerSecond;
|
|
||||||
long nowSeconds = DateTime.Now.Ticks / TimeSpan.TicksPerSecond;
|
|
||||||
long secondsDifference = notAfterSeconds - nowSeconds;
|
|
||||||
if (secondsDifference > Int32.MaxValue)
|
|
||||||
secondsDifference = Int32.MaxValue;
|
|
||||||
long _30days = new TimeSpan(30, 0, 0, 0).Ticks / TimeSpan.TicksPerSecond;
|
|
||||||
|
|
||||||
int max = (int)secondsDifference;
|
|
||||||
int min = (int)_30days;
|
|
||||||
int updateDelayInt = random.Next(min, max);
|
|
||||||
TimeSpan updateDelayTimespan = TimeSpan.FromSeconds(updateDelayInt);
|
|
||||||
|
|
||||||
X509V2CrlGenerator crlGenerator = new X509V2CrlGenerator();
|
|
||||||
crlGenerator.SetIssuerDN(issuer.IssuerDN);
|
|
||||||
crlGenerator.SetThisUpdate(DateTime.Now);
|
|
||||||
crlGenerator.SetNextUpdate(DateTime.Now + updateDelayTimespan);
|
|
||||||
crlGenerator.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, X509ExtensionUtilities.CreateAuthorityKeyIdentifier(issuer));
|
|
||||||
crlGenerator.AddExtension(X509Extensions.CrlNumber, false, new CrlNumber(BigInteger.One));
|
|
||||||
|
|
||||||
foreach (long revokedSerial in revokedSerials)
|
|
||||||
{
|
|
||||||
crlGenerator.AddCrlEntry(BigInteger.ValueOf(revokedSerial),DateTime.Now, CrlReason.PrivilegeWithdrawn);
|
|
||||||
}
|
|
||||||
|
|
||||||
const string signatureAlgorithm = "SHA256WithRSA";
|
|
||||||
Asn1SignatureFactory signatureFactory = new Asn1SignatureFactory(signatureAlgorithm, issuerPrivateKey.Private, random);
|
|
||||||
X509Crl crl = crlGenerator.Generate(signatureFactory);
|
|
||||||
return crl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] ExportCrl(X509Crl crl)
|
|
||||||
{
|
|
||||||
return crl.GetEncoded();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static X509Crl ImportCrl(byte[] buffer)
|
|
||||||
{
|
|
||||||
X509Crl result = new X509Crl(buffer);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool ValidateCertificateAgainstCrl(X509Certificate certificate, X509Crl crl)
|
|
||||||
{
|
|
||||||
BigInteger mySerial = certificate.SerialNumber;
|
|
||||||
ISet<X509CrlEntry> x509CrlEntries = crl.GetRevokedCertificates();
|
|
||||||
foreach (X509CrlEntry entry in x509CrlEntries)
|
|
||||||
{
|
|
||||||
BigInteger entrySerial = entry.SerialNumber;
|
|
||||||
if (entrySerial.Equals(mySerial))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] GetSophiaNetExtensionFromCertificate(X509Certificate cert)
|
|
||||||
{
|
|
||||||
DerObjectIdentifier sophiaNetExtensionId = new DerObjectIdentifier("1.3.6.1.3.545127833961986897372532.1");
|
|
||||||
X509Extension x509Extension = cert.GetExtension(sophiaNetExtensionId);
|
|
||||||
Asn1OctetString octetString = x509Extension.Value;
|
|
||||||
Stream octetStream = octetString.Parser.GetOctetStream();
|
|
||||||
Asn1InputStream asn1Reader = new Asn1InputStream(octetStream);
|
|
||||||
DerOctetString readObject = (DerOctetString)asn1Reader.ReadObject();
|
|
||||||
byte[] result = readObject.GetOctets();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] SignFile(byte[] toBeSigned, AsymmetricKeyParameter privateKey)
|
|
||||||
{
|
|
||||||
RsaDigestSigner signer = new RsaDigestSigner(new Sha256Digest());
|
|
||||||
signer.Init(true, privateKey);
|
|
||||||
signer.BlockUpdate(toBeSigned, 0, toBeSigned.Length);
|
|
||||||
return signer.GenerateSignature();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool ValidateSignedFile(byte[] signed, byte[] signature, AsymmetricKeyParameter publicKey)
|
|
||||||
{
|
|
||||||
RsaDigestSigner signer = new RsaDigestSigner(new Sha256Digest());
|
|
||||||
signer.Init(false, publicKey);
|
|
||||||
signer.BlockUpdate(signed, 0, signed.Length);
|
|
||||||
|
|
||||||
bool isValid = signer.VerifySignature(signature);
|
|
||||||
return isValid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,88 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Sophia.Net.DRM
|
|
||||||
{
|
|
||||||
public class SophiaNetEntitlementCollection
|
|
||||||
{
|
|
||||||
public SophiaNetEntitlementCollection(params Guid[] guids)
|
|
||||||
{
|
|
||||||
_backend = new Guid[guids.Length];
|
|
||||||
Array.Copy(guids,0,_backend,0, guids.Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SophiaNetEntitlementCollection(byte[] buffer)
|
|
||||||
{
|
|
||||||
_backend = new Guid[buffer.Length / 16];
|
|
||||||
for (int i = 0; i < buffer.Length; i += 16)
|
|
||||||
{
|
|
||||||
Span<byte> part = new Span<byte>(buffer, i, 16);
|
|
||||||
_backend[i / 16] = new Guid(part);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] Serialize()
|
|
||||||
{
|
|
||||||
byte[] outBuffer = new byte[_backend.Length * 16];
|
|
||||||
for (int i = 0; i < _backend.Length; i++)
|
|
||||||
{
|
|
||||||
byte[] iBuffer = _backend[i].ToByteArray();
|
|
||||||
Array.Copy(iBuffer, 0, outBuffer, i * 16, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
return outBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Guid[] _backend;
|
|
||||||
|
|
||||||
public bool HasEntitlement(Guid check)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < _backend.Length; i++)
|
|
||||||
{
|
|
||||||
if (_backend[i].Equals(check))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected bool Equals(SophiaNetEntitlementCollection that)
|
|
||||||
{
|
|
||||||
if (this._backend.Length != that._backend.Length)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (int i = 0; i < this._backend.Length; i++)
|
|
||||||
{
|
|
||||||
Guid mine = this._backend[i];
|
|
||||||
Guid theirs = that._backend[i];
|
|
||||||
if (!mine.Equals(theirs))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object? obj)
|
|
||||||
{
|
|
||||||
if (ReferenceEquals(null, obj))
|
|
||||||
return false;
|
|
||||||
if (ReferenceEquals(this, obj))
|
|
||||||
return true;
|
|
||||||
if (obj.GetType() != this.GetType())
|
|
||||||
return false;
|
|
||||||
return Equals((SophiaNetEntitlementCollection)obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode()
|
|
||||||
{
|
|
||||||
long result = 0;
|
|
||||||
for (int i = 0; i < _backend.Length; i++)
|
|
||||||
{
|
|
||||||
result += _backend[i].GetHashCode();
|
|
||||||
}
|
|
||||||
return (int)result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user