diff --git a/.gitignore b/.gitignore
index c4721f7..263141f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,3 +11,11 @@
/Voile.Sqlite/bin/Debug/net8.0
/Voile.Sqlite/obj/Debug/net8.0
/Voile.Sqlite/obj
+/Sophia.Net.DRM/.vs/ProjectEvaluation
+/Sophia.Net.DRM/.vs/Sophia.Net.DRM/CopilotIndices/17.14.1431.25910
+/Sophia.Net.DRM/.vs/Sophia.Net.DRM/DesignTimeBuild
+/Sophia.Net.DRM/.vs/Sophia.Net.DRM/FileContentIndex
+/Sophia.Net.DRM/.vs/Sophia.Net.DRM/v17
+/Sophia.Net.DRM/bin/Debug/net8.0
+/Sophia.Net.DRM/obj/Debug/net8.0
+/Sophia.Net.DRM/obj
diff --git a/Voile.Sqlite/Voile.SQLite.csproj b/Sophia.Net.DRM/Sophia.Net.DRM.csproj
similarity index 60%
rename from Voile.Sqlite/Voile.SQLite.csproj
rename to Sophia.Net.DRM/Sophia.Net.DRM.csproj
index aa499ab..7867787 100644
--- a/Voile.Sqlite/Voile.SQLite.csproj
+++ b/Sophia.Net.DRM/Sophia.Net.DRM.csproj
@@ -7,8 +7,7 @@
-
-
+
diff --git a/Sophia.Net.DRM/Sophia.Net.DRM.sln b/Sophia.Net.DRM/Sophia.Net.DRM.sln
new file mode 100644
index 0000000..66643b3
--- /dev/null
+++ b/Sophia.Net.DRM/Sophia.Net.DRM.sln
@@ -0,0 +1,31 @@
+
+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
diff --git a/Sophia.Net.DRM/SophiaNetDrmApi.cs b/Sophia.Net.DRM/SophiaNetDrmApi.cs
new file mode 100644
index 0000000..4ae94b3
--- /dev/null
+++ b/Sophia.Net.DRM/SophiaNetDrmApi.cs
@@ -0,0 +1,350 @@
+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 usageList = new List();
+ 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 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;
+ }
+ }
+}
diff --git a/Sophia.Net.DRM/SophiaNetEntitlements.cs b/Sophia.Net.DRM/SophiaNetEntitlements.cs
new file mode 100644
index 0000000..7103b53
--- /dev/null
+++ b/Sophia.Net.DRM/SophiaNetEntitlements.cs
@@ -0,0 +1,88 @@
+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 part = new Span(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;
+ }
+ }
+}
diff --git a/Voile.Sqlite/Class1.cs b/Voile.Sqlite/Class1.cs
deleted file mode 100644
index 5fc054e..0000000
--- a/Voile.Sqlite/Class1.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-//using Microsoft.Data.Sqlite;
-
-namespace Voile.Sqlite
-{
- public class Class1
- {
- public void Run()
- {
- /*SqliteConnectionStringBuilder scsb = new SqliteConnectionStringBuilder();
- scsb.DataSource = "blyat.db";
- SqliteConnection sc = new SqliteConnection(scsb.ConnectionString);
- sc.Open();*/
-
- }
- }
-}
diff --git a/Voile.slnx b/Voile.slnx
index 443eaeb..ed7b54a 100644
--- a/Voile.slnx
+++ b/Voile.slnx
@@ -1,5 +1,5 @@
-
+
diff --git a/Voile/FirstRunWizard.Designer.cs b/Voile/FirstRunWizard.Designer.cs
index b7ff3f8..a7840a4 100644
--- a/Voile/FirstRunWizard.Designer.cs
+++ b/Voile/FirstRunWizard.Designer.cs
@@ -31,17 +31,28 @@
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FirstRunWizard));
pictureBox1 = new PictureBox();
tabControl1 = new TabControl();
- tabPage1 = new TabPage();
+ tabPageWelcome = new TabPage();
label2 = new Label();
label1 = new Label();
- radioButton2 = new RadioButton();
- radioButton1 = new RadioButton();
- tabPage2 = new TabPage();
- button1 = new Button();
- button2 = new Button();
+ radioButtonAmExpert = new RadioButton();
+ radioButtonAmBegginer = new RadioButton();
+ tabPageLicense = new TabPage();
+ pictureBox2 = new PictureBox();
+ label4 = new Label();
+ radioButtonNoLicense = new RadioButton();
+ buttonLoadLicenseFile = new Button();
+ buttonValidateLicense = new Button();
+ textBox1 = new TextBox();
+ radioButtonHasLicense = new RadioButton();
+ label3 = new Label();
+ buttonNext = new Button();
+ buttonBack = new Button();
+ openFileDialogCertificate = new OpenFileDialog();
((System.ComponentModel.ISupportInitialize)pictureBox1).BeginInit();
tabControl1.SuspendLayout();
- tabPage1.SuspendLayout();
+ tabPageWelcome.SuspendLayout();
+ tabPageLicense.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)pictureBox2).BeginInit();
SuspendLayout();
//
// pictureBox1
@@ -56,27 +67,27 @@
//
// tabControl1
//
- tabControl1.Controls.Add(tabPage1);
- tabControl1.Controls.Add(tabPage2);
+ tabControl1.Controls.Add(tabPageWelcome);
+ tabControl1.Controls.Add(tabPageLicense);
tabControl1.Location = new Point(138, 12);
tabControl1.Name = "tabControl1";
tabControl1.SelectedIndex = 0;
tabControl1.Size = new Size(356, 412);
tabControl1.TabIndex = 1;
//
- // tabPage1
+ // tabPageWelcome
//
- tabPage1.Controls.Add(label2);
- tabPage1.Controls.Add(label1);
- tabPage1.Controls.Add(radioButton2);
- tabPage1.Controls.Add(radioButton1);
- tabPage1.Location = new Point(4, 24);
- tabPage1.Name = "tabPage1";
- tabPage1.Padding = new Padding(3);
- tabPage1.Size = new Size(348, 384);
- tabPage1.TabIndex = 0;
- tabPage1.Text = "Welcome!";
- tabPage1.UseVisualStyleBackColor = true;
+ tabPageWelcome.Controls.Add(label2);
+ tabPageWelcome.Controls.Add(label1);
+ tabPageWelcome.Controls.Add(radioButtonAmExpert);
+ tabPageWelcome.Controls.Add(radioButtonAmBegginer);
+ tabPageWelcome.Location = new Point(4, 24);
+ tabPageWelcome.Name = "tabPageWelcome";
+ tabPageWelcome.Padding = new Padding(3);
+ tabPageWelcome.Size = new Size(348, 384);
+ tabPageWelcome.TabIndex = 0;
+ tabPageWelcome.Text = "Welcome!";
+ tabPageWelcome.UseVisualStyleBackColor = true;
//
// label2
//
@@ -96,65 +107,161 @@
label1.TabIndex = 2;
label1.Text = "(You can change these options later!)";
//
- // radioButton2
+ // radioButtonAmExpert
//
- radioButton2.AutoSize = true;
- radioButton2.Location = new Point(6, 271);
- radioButton2.Name = "radioButton2";
- radioButton2.Size = new Size(299, 34);
- radioButton2.TabIndex = 1;
- radioButton2.TabStop = true;
- radioButton2.Text = "I’m an expert. Let me choose my own database and \r\nstorage options.";
- radioButton2.UseVisualStyleBackColor = true;
+ radioButtonAmExpert.AutoSize = true;
+ radioButtonAmExpert.Location = new Point(6, 271);
+ radioButtonAmExpert.Name = "radioButtonAmExpert";
+ radioButtonAmExpert.Size = new Size(299, 34);
+ radioButtonAmExpert.TabIndex = 1;
+ radioButtonAmExpert.Text = "I’m an expert. Let me choose my own database and \r\nstorage options.";
+ radioButtonAmExpert.UseVisualStyleBackColor = true;
+ radioButtonAmExpert.CheckedChanged += radioButtonAmExpert_CheckedChanged;
//
- // radioButton1
+ // radioButtonAmBegginer
//
- radioButton1.AutoSize = true;
- radioButton1.Checked = true;
- radioButton1.Location = new Point(6, 246);
- radioButton1.Name = "radioButton1";
- radioButton1.Size = new Size(298, 19);
- radioButton1.TabIndex = 0;
- radioButton1.TabStop = true;
- radioButton1.Text = "I’m a beginner. Set things up for me automatically. ";
- radioButton1.UseVisualStyleBackColor = true;
+ radioButtonAmBegginer.AutoSize = true;
+ radioButtonAmBegginer.Location = new Point(6, 246);
+ radioButtonAmBegginer.Name = "radioButtonAmBegginer";
+ radioButtonAmBegginer.Size = new Size(298, 19);
+ radioButtonAmBegginer.TabIndex = 0;
+ radioButtonAmBegginer.Text = "I’m a beginner. Set things up for me automatically. ";
+ radioButtonAmBegginer.UseVisualStyleBackColor = true;
+ radioButtonAmBegginer.CheckedChanged += radioButtonAmBegginer_CheckedChanged;
//
- // tabPage2
+ // tabPageLicense
//
- tabPage2.Location = new Point(4, 24);
- tabPage2.Name = "tabPage2";
- tabPage2.Padding = new Padding(3);
- tabPage2.Size = new Size(348, 384);
- tabPage2.TabIndex = 1;
- tabPage2.Text = "tabPage2";
- tabPage2.UseVisualStyleBackColor = true;
+ tabPageLicense.Controls.Add(pictureBox2);
+ tabPageLicense.Controls.Add(label4);
+ tabPageLicense.Controls.Add(radioButtonNoLicense);
+ tabPageLicense.Controls.Add(buttonLoadLicenseFile);
+ tabPageLicense.Controls.Add(buttonValidateLicense);
+ tabPageLicense.Controls.Add(textBox1);
+ tabPageLicense.Controls.Add(radioButtonHasLicense);
+ tabPageLicense.Controls.Add(label3);
+ tabPageLicense.Location = new Point(4, 24);
+ tabPageLicense.Name = "tabPageLicense";
+ tabPageLicense.Padding = new Padding(3);
+ tabPageLicense.Size = new Size(348, 384);
+ tabPageLicense.TabIndex = 1;
+ tabPageLicense.Text = "License";
+ tabPageLicense.UseVisualStyleBackColor = true;
//
- // button1
+ // pictureBox2
//
- button1.Location = new Point(419, 430);
- button1.Name = "button1";
- button1.Size = new Size(75, 23);
- button1.TabIndex = 2;
- button1.Text = "Next >";
- button1.UseVisualStyleBackColor = true;
+ pictureBox2.Image = Properties.Resources.SETUPAPI_18_1_32x32x4;
+ pictureBox2.Location = new Point(127, 262);
+ pictureBox2.Name = "pictureBox2";
+ pictureBox2.Size = new Size(32, 32);
+ pictureBox2.TabIndex = 7;
+ pictureBox2.TabStop = false;
+ pictureBox2.Click += pictureBox2_Click;
//
- // button2
+ // label4
//
- button2.Enabled = false;
- button2.Location = new Point(338, 430);
- button2.Name = "button2";
- button2.Size = new Size(75, 23);
- button2.TabIndex = 3;
- button2.Text = "< Back";
- button2.UseVisualStyleBackColor = true;
+ label4.AutoSize = true;
+ label4.Location = new Point(22, 344);
+ label4.Name = "label4";
+ label4.Size = new Size(299, 30);
+ label4.TabIndex = 6;
+ label4.Text = "(You can also change between Licensed and Shareware \r\nmode later!)";
+ //
+ // radioButtonNoLicense
+ //
+ radioButtonNoLicense.AutoSize = true;
+ radioButtonNoLicense.Location = new Point(6, 307);
+ radioButtonNoLicense.Name = "radioButtonNoLicense";
+ radioButtonNoLicense.Size = new Size(309, 34);
+ radioButtonNoLicense.TabIndex = 5;
+ radioButtonNoLicense.Text = "No license yet — I’d like to use the shareware version, \r\nor request a license later.";
+ radioButtonNoLicense.UseVisualStyleBackColor = true;
+ radioButtonNoLicense.CheckedChanged += radioButtonNoLicense_CheckedChanged;
+ //
+ // buttonLoadLicenseFile
+ //
+ buttonLoadLicenseFile.Enabled = false;
+ buttonLoadLicenseFile.Location = new Point(246, 262);
+ buttonLoadLicenseFile.Name = "buttonLoadLicenseFile";
+ buttonLoadLicenseFile.Size = new Size(75, 39);
+ buttonLoadLicenseFile.TabIndex = 4;
+ buttonLoadLicenseFile.Text = "Load License File";
+ buttonLoadLicenseFile.UseVisualStyleBackColor = true;
+ buttonLoadLicenseFile.Click += buttonLoadLicenseFile_Click;
+ //
+ // buttonValidateLicense
+ //
+ buttonValidateLicense.Enabled = false;
+ buttonValidateLicense.Location = new Point(165, 262);
+ buttonValidateLicense.Name = "buttonValidateLicense";
+ buttonValidateLicense.Size = new Size(75, 39);
+ buttonValidateLicense.TabIndex = 3;
+ buttonValidateLicense.Text = "Validate License";
+ buttonValidateLicense.UseVisualStyleBackColor = true;
+ buttonValidateLicense.Click += buttonValidateLicense_Click;
+ //
+ // textBox1
+ //
+ textBox1.Enabled = false;
+ textBox1.Location = new Point(17, 233);
+ textBox1.Name = "textBox1";
+ textBox1.Size = new Size(304, 23);
+ textBox1.TabIndex = 2;
+ //
+ // radioButtonHasLicense
+ //
+ radioButtonHasLicense.AutoSize = true;
+ radioButtonHasLicense.Location = new Point(3, 208);
+ radioButtonHasLicense.Name = "radioButtonHasLicense";
+ radioButtonHasLicense.Size = new Size(189, 19);
+ radioButtonHasLicense.TabIndex = 1;
+ radioButtonHasLicense.Text = "Yes, I have a license file to load.";
+ radioButtonHasLicense.UseVisualStyleBackColor = true;
+ radioButtonHasLicense.CheckedChanged += radioButton3_CheckedChanged;
+ //
+ // label3
+ //
+ label3.AutoSize = true;
+ label3.Location = new Point(6, 3);
+ label3.Name = "label3";
+ label3.Size = new Size(337, 120);
+ label3.TabIndex = 0;
+ label3.Text = resources.GetString("label3.Text");
+ //
+ // buttonNext
+ //
+ buttonNext.Enabled = false;
+ buttonNext.Location = new Point(419, 430);
+ buttonNext.Name = "buttonNext";
+ buttonNext.Size = new Size(75, 23);
+ buttonNext.TabIndex = 2;
+ buttonNext.Text = "Next >";
+ buttonNext.UseVisualStyleBackColor = true;
+ buttonNext.Click += buttonNext_Click;
+ //
+ // buttonBack
+ //
+ buttonBack.Enabled = false;
+ buttonBack.Location = new Point(338, 430);
+ buttonBack.Name = "buttonBack";
+ buttonBack.Size = new Size(75, 23);
+ buttonBack.TabIndex = 3;
+ buttonBack.Text = "< Back";
+ buttonBack.UseVisualStyleBackColor = true;
+ //
+ // openFileDialogCertificate
+ //
+ openFileDialogCertificate.DefaultExt = "cer";
+ openFileDialogCertificate.FileName = "openFileDialog1";
+ openFileDialogCertificate.Filter = "X.509 Certificate (*.cer)|*.cer";
+ openFileDialogCertificate.Title = "Open Voile License File";
//
// FirstRunWizard
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(502, 465);
- Controls.Add(button2);
- Controls.Add(button1);
+ Controls.Add(buttonBack);
+ Controls.Add(buttonNext);
Controls.Add(tabControl1);
Controls.Add(pictureBox1);
FormBorderStyle = FormBorderStyle.FixedSingle;
@@ -165,8 +272,11 @@
Text = "Voile - First Run Wizard";
((System.ComponentModel.ISupportInitialize)pictureBox1).EndInit();
tabControl1.ResumeLayout(false);
- tabPage1.ResumeLayout(false);
- tabPage1.PerformLayout();
+ tabPageWelcome.ResumeLayout(false);
+ tabPageWelcome.PerformLayout();
+ tabPageLicense.ResumeLayout(false);
+ tabPageLicense.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)pictureBox2).EndInit();
ResumeLayout(false);
}
@@ -174,13 +284,22 @@
private PictureBox pictureBox1;
private TabControl tabControl1;
- private TabPage tabPage1;
- private TabPage tabPage2;
- private Button button1;
- private Button button2;
- private RadioButton radioButton1;
- private RadioButton radioButton2;
+ private TabPage tabPageWelcome;
+ private TabPage tabPageLicense;
+ private Button buttonNext;
+ private Button buttonBack;
+ private RadioButton radioButtonAmBegginer;
+ private RadioButton radioButtonAmExpert;
private Label label1;
private Label label2;
+ private Label label3;
+ private RadioButton radioButtonHasLicense;
+ private RadioButton radioButtonNoLicense;
+ private Button buttonLoadLicenseFile;
+ private Button buttonValidateLicense;
+ private TextBox textBox1;
+ private Label label4;
+ private PictureBox pictureBox2;
+ private OpenFileDialog openFileDialogCertificate;
}
}
\ No newline at end of file
diff --git a/Voile/FirstRunWizard.cs b/Voile/FirstRunWizard.cs
index 9c190dc..965002f 100644
--- a/Voile/FirstRunWizard.cs
+++ b/Voile/FirstRunWizard.cs
@@ -1,4 +1,7 @@
-using System;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.X509;
+using Sophia.Net.DRM;
+using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
@@ -7,6 +10,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
+using Voile.Properties;
namespace Voile
{
@@ -19,8 +23,22 @@ namespace Voile
}
private TabPage[] allPages;
- public void DisplayTabPage(int target)
+ private int currentTabPage;
+ private Stack pastPages;
+
+ private bool beginnerMode;
+ private FileInfo licenceCertificateFileInfo;
+ private byte[] licenseBuffer;
+ private int licenseState;
+ private X509Certificate licenseCertificate;
+
+ public void DisplayTabPage(int target, bool isGoingBack = false)
{
+ if (pastPages == null)
+ pastPages = new Stack();
+ else
+ pastPages.Push(target);
+
if (allPages == null)
{
allPages = new TabPage[tabControl1.TabPages.Count];
@@ -29,9 +47,180 @@ namespace Voile
allPages[i] = tabControl1.TabPages[i];
}
}
-
+
tabControl1.TabPages.Clear();
tabControl1.TabPages.Add(allPages[target]);
+ currentTabPage = target;
+ RefreshView();
+ }
+
+ void RefreshView()
+ {
+ buttonBack.Enabled = false;
+ buttonNext.Enabled = false;
+
+ if (pastPages != null)
+ {
+ if (pastPages.Count > 0)
+ {
+ buttonBack.Enabled = true;
+ }
+ }
+
+ switch (currentTabPage)
+ {
+ case 0:
+ beginnerMode = radioButtonAmBegginer.Checked;
+ buttonNext.Enabled = radioButtonAmBegginer.Checked || radioButtonAmExpert.Checked;
+ break;
+ case 1:
+ buttonValidateLicense.Enabled = ((licenceCertificateFileInfo != null) & radioButtonHasLicense.Checked);
+ buttonLoadLicenseFile.Enabled = radioButtonHasLicense.Checked;
+ pictureBox2.Visible = radioButtonHasLicense.Checked;
+ if (pictureBox2.Visible)
+ {
+ switch(licenseState)
+ {
+ case 0: //Noch nichts geladen.
+ pictureBox2.Image = Resources.SETUPAPI_18_1_32x32x4; //Fragezeichen
+ break;
+ case 1: //Root cert konnte nicht geladen werden.
+ case 2: //Lizenz file konnte nicht geladen werden.
+ case 3: //Lizenzzertifikat wurde nicht von sophia.net ausgestellt.
+ case 4: //Lizennzertifikat enthält keine sophia.net extensions
+ case 5: //sophia.net extension ist leer
+ case 7: //sophia.net extension hat ungültige länge
+ pictureBox2.Image = Resources.TRFFC10C_1_32x32x4; //rote Ampel
+ break;
+ case 6: //gültige lizenz
+ pictureBox2.Image = Resources.TRFFC10A_1_32x32x4; //grüne Ampel
+ break;
+ case 8:
+ default:
+ pictureBox2.Image = Resources.iblicense_133_1_32x32x4; //Ausrufezeichen
+ licenseState = 8;
+ break;
+ }
+ }
+ break;
+ default:
+ MessageBox.Show("Could not find handler for the current tab page.");
+ return;
+ }
+ }
+
+ private void radioButton3_CheckedChanged(object sender, EventArgs e)
+ {
+ RefreshView();
+ }
+
+ private void radioButtonAmBegginer_CheckedChanged(object sender, EventArgs e)
+ {
+ RefreshView();
+ }
+
+ private void radioButtonAmExpert_CheckedChanged(object sender, EventArgs e)
+ {
+ RefreshView();
+ }
+
+ private void radioButtonNoLicense_CheckedChanged(object sender, EventArgs e)
+ {
+ RefreshView();
+ }
+
+ private void pictureBox2_Click(object sender, EventArgs e)
+ {
+
+ }
+
+ private void buttonNext_Click(object sender, EventArgs e)
+ {
+ if (currentTabPage == 0)
+ {
+ DisplayTabPage(1);
+ }
+ }
+
+ private void buttonLoadLicenseFile_Click(object sender, EventArgs e)
+ {
+ if (openFileDialogCertificate.ShowDialog() == DialogResult.OK)
+ {
+ licenceCertificateFileInfo = new FileInfo(openFileDialogCertificate.FileName);
+ licenseBuffer = File.ReadAllBytes(licenceCertificateFileInfo.FullName);
+ textBox1.Text = licenceCertificateFileInfo.FullName;
+ licenseState = 0;
+ pictureBox2.Image = Resources.SETUPAPI_18_1_32x32x4;
+ }
+ RefreshView();
+ }
+
+ private void buttonValidateLicense_Click(object sender, EventArgs e)
+ {
+ VoileContext voileContext = VoileContext.GetContext();
+
+ if (voileContext.SophiaNetRootCertificate == null)
+ {
+ try
+ {
+ byte[] sophianetCertBuffer = Resources.sophianet_cert;
+ voileContext.SophiaNetRootCertificate = SophiaNetDrmApi.ImportCertificate(sophianetCertBuffer);
+ }
+ catch (Exception ex)
+ {
+ licenseState = 1;
+ RefreshView();
+ return;
+ }
+ }
+
+ try
+ {
+ licenseCertificate = SophiaNetDrmApi.ImportCertificate(licenseBuffer);
+ }
+ catch (Exception f)
+ {
+ licenseState = 2;
+ RefreshView();
+ return;
+ }
+
+ bool certificateChainValid = SophiaNetDrmApi.ValidateCertificateChain(licenseCertificate, voileContext.SophiaNetRootCertificate);
+ if (!certificateChainValid)
+ {
+ licenseState = 3;
+ RefreshView();
+ return;
+ }
+
+ byte[] sophiaNetExtensionBuffer;
+ try
+ {
+ sophiaNetExtensionBuffer = SophiaNetDrmApi.GetSophiaNetExtensionFromCertificate(licenseCertificate);
+ }
+ catch (Exception g)
+ {
+ licenseState = 4;
+ RefreshView();
+ return;
+ }
+
+ if (sophiaNetExtensionBuffer.Length == 0)
+ {
+ licenseState = 5;
+ RefreshView();
+ return;
+ }
+ if (sophiaNetExtensionBuffer.Length % 16 != 0)
+ {
+ licenseState = 7;
+ RefreshView();
+ return;
+ }
+
+ licenseState = 6;
+ RefreshView();
+ return;
}
}
}
diff --git a/Voile/FirstRunWizard.resx b/Voile/FirstRunWizard.resx
index 55878d3..d12d1bf 100644
--- a/Voile/FirstRunWizard.resx
+++ b/Voile/FirstRunWizard.resx
@@ -135,4 +135,17 @@ up automatically so you can start using the app right away.
How would you like to continue?
+
+ Before we continue, let’s take a moment to set up your license.
+
+Voile is available as shareware, which means you can use it
+for free for personal, non‑commercial projects. If you’re using
+Voile in a professional setting — or if you’d simply like
+to support the ongoing development — you can activate
+a license. Some advanced features also become available
+once a license is installed.
+
+
+ 17, 17
+
\ No newline at end of file
diff --git a/Voile/Properties/Resources.Designer.cs b/Voile/Properties/Resources.Designer.cs
index 3a403f7..4c7e1e6 100644
--- a/Voile/Properties/Resources.Designer.cs
+++ b/Voile/Properties/Resources.Designer.cs
@@ -100,6 +100,16 @@ namespace Voile.Properties {
}
}
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap iblicense_133_1_32x32x4 {
+ get {
+ object obj = ResourceManager.GetObject("iblicense_133_1_32x32x4", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
///
/// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
///
@@ -110,6 +120,26 @@ namespace Voile.Properties {
}
}
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap SETUPAPI_18_1_32x32x4 {
+ get {
+ object obj = ResourceManager.GetObject("SETUPAPI_18_1_32x32x4", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
+ ///
+ internal static byte[] sophianet_cert {
+ get {
+ object obj = ResourceManager.GetObject("sophianet_cert", resourceCulture);
+ return ((byte[])(obj));
+ }
+ }
+
///
/// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
///
@@ -120,6 +150,26 @@ namespace Voile.Properties {
}
}
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap TRFFC10A_1_32x32x4 {
+ get {
+ object obj = ResourceManager.GetObject("TRFFC10A_1_32x32x4", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap TRFFC10C_1_32x32x4 {
+ get {
+ object obj = ResourceManager.GetObject("TRFFC10C_1_32x32x4", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
///
/// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
///
diff --git a/Voile/Properties/Resources.resx b/Voile/Properties/Resources.resx
index 3d643ce..ebe4724 100644
--- a/Voile/Properties/Resources.resx
+++ b/Voile/Properties/Resources.resx
@@ -131,12 +131,27 @@
..\Resources\H_POINT.CUR;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Mauszeiger
+
+ ..\Resources\iblicense_133_1_32x32x4.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
..\Resources\inetwiz_100_1_32x32x4.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+ ..\Resources\SETUPAPI_18_1_32x32x4.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\sophianet-cert.cer;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
..\Resources\technlgy.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+ ..\Resources\TRFFC10A_1_32x32x4.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\TRFFC10C_1_32x32x4.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
..\Resources\URLPKR_141_1_32x32x4.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
diff --git a/Voile/Resources/SETUPAPI_18_1_32x32x4.png b/Voile/Resources/SETUPAPI_18_1_32x32x4.png
new file mode 100644
index 0000000..6804e38
Binary files /dev/null and b/Voile/Resources/SETUPAPI_18_1_32x32x4.png differ
diff --git a/Voile/Resources/TRFFC09_1_32x32x4.png b/Voile/Resources/TRFFC09_1_32x32x4.png
new file mode 100644
index 0000000..409b609
Binary files /dev/null and b/Voile/Resources/TRFFC09_1_32x32x4.png differ
diff --git a/Voile/Resources/TRFFC10A_1_32x32x4.png b/Voile/Resources/TRFFC10A_1_32x32x4.png
new file mode 100644
index 0000000..67ccafc
Binary files /dev/null and b/Voile/Resources/TRFFC10A_1_32x32x4.png differ
diff --git a/Voile/Resources/TRFFC10B_1_32x32x4.png b/Voile/Resources/TRFFC10B_1_32x32x4.png
new file mode 100644
index 0000000..f468171
Binary files /dev/null and b/Voile/Resources/TRFFC10B_1_32x32x4.png differ
diff --git a/Voile/Resources/TRFFC10C_1_32x32x4.png b/Voile/Resources/TRFFC10C_1_32x32x4.png
new file mode 100644
index 0000000..85e5c8e
Binary files /dev/null and b/Voile/Resources/TRFFC10C_1_32x32x4.png differ
diff --git a/Voile/Resources/iblicense_133_1_32x32x4.png b/Voile/Resources/iblicense_133_1_32x32x4.png
new file mode 100644
index 0000000..71e3edb
Binary files /dev/null and b/Voile/Resources/iblicense_133_1_32x32x4.png differ
diff --git a/Voile/Resources/sophianet-cert.cer b/Voile/Resources/sophianet-cert.cer
new file mode 100644
index 0000000..35a7538
Binary files /dev/null and b/Voile/Resources/sophianet-cert.cer differ
diff --git a/Voile/Voile.csproj b/Voile/Voile.csproj
index 8848544..5a9e17a 100644
--- a/Voile/Voile.csproj
+++ b/Voile/Voile.csproj
@@ -21,7 +21,7 @@
-
+
diff --git a/Voile/VoileContext.cs b/Voile/VoileContext.cs
index 95a3953..7987cdc 100644
--- a/Voile/VoileContext.cs
+++ b/Voile/VoileContext.cs
@@ -1,4 +1,5 @@
-using skyscraper5.Skyscraper;
+using Org.BouncyCastle.X509;
+using skyscraper5.Skyscraper;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -47,5 +48,6 @@ namespace Voile
}
public Ini Ini { get; set; }
+ public X509Certificate SophiaNetRootCertificate { get; internal set; }
}
}