private async void DeleteExistingFromStore(string storePath) { if (String.IsNullOrEmpty(storePath)) { return; } using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(storePath)) { X509Certificate2Collection certificates = await store.Enumerate(); foreach (var certificate in certificates) { if (store.GetPrivateKeyFilePath(certificate.Thumbprint) != null) { continue; } List <string> fields = Utils.ParseDistinguishedName(certificate.Subject); if (fields.Contains("CN=UA Local Discovery Server")) { continue; } DirectoryCertificateStore ds = store as DirectoryCertificateStore; if (ds != null) { string path = Utils.GetAbsoluteFilePath(m_application.CertificatePublicKeyPath, true, false, false); if (path != null) { if (String.Compare(path, ds.GetPublicKeyFilePath(certificate.Thumbprint), StringComparison.OrdinalIgnoreCase) == 0) { continue; } } path = Utils.GetAbsoluteFilePath(m_application.CertificatePrivateKeyPath, true, false, false); if (path != null) { if (String.Compare(path, ds.GetPrivateKeyFilePath(certificate.Thumbprint), StringComparison.OrdinalIgnoreCase) == 0) { continue; } } } await store.Delete(certificate.Thumbprint); } } }
async void OnClick(object sender, EventArgs e) { try { if (ClickedButton.Text == "Download certificate to server") { //download new cert and issuer to server if (await UpdateCertificateSelfSignedNoPrivateKey()) { // add issuer and trusted certs to client stores AddTrustListToStore(this._PushClient.Application.ApplicationConfiguration.SecurityConfiguration, this._PushClient.ReadTrustList()); DirectoryCertificateStore issuerStore = (DirectoryCertificateStore)CertificateStoreIdentifier.OpenStore(this._PushClient.Application.ApplicationConfiguration.SecurityConfiguration.TrustedIssuerCertificates.StorePath); // add IssuerCrl to client stores var issuerCrl = Convert.FromBase64String(this._crl); File.WriteAllBytes(issuerStore.Directory.ToString() + "/crl/" + Utils.CertFileName(this._issuer) + ".crl", issuerCrl); //Accept the CSR of OPC Vault service var result = await AcceptAsync(this._requestid); await Xamarin.Forms.Application.Current.MainPage.DisplayAlert(result, "", "OK"); listView.ItemsSource = RefreshData(); this._PushClient.Disconnect(); ClickedButton.IsVisible = false; } } else { if (this._PushClient.IsConnected) { byte[] nonce = new byte[0]; var csr = Convert.ToBase64String(this._PushClient.CreateSigningRequest(null, this._PushClient.ApplicationCertificateType, null, false, null)); if (csr != null) { var CreateSigningRequest = await StartSigningAsync(((ApplicationRecordApiModel)this.BindingContext).ApplicationId, csr); string ApplicationUri = ((ApplicationRecordApiModel)this.BindingContext).ApplicationUri; string ApplicationName = ((ApplicationRecordApiModel)this.BindingContext).ApplicationName; var genNewCertPage = new GenNewCertPage(this._opcVaultServiceClient, ApplicationUri, ApplicationName); genNewCertPage.BindingContext = CreateSigningRequest; this._PushClient.Disconnect(); await Navigation.PushAsync(genNewCertPage); } } } } catch (Exception ee) { await Xamarin.Forms.Application.Current.MainPage.DisplayAlert("An error has occurred", "Exception message: " + ee.Message, "Dismiss"); } }
/// <summary> /// Returns the token from the cert in the given cert store. /// </summary> public async static Task <string> ReadAsync(string name, string storeType, string storePath) { string token = null; // handle each store type differently switch (storeType) { case CertificateStoreType.Directory: { // search a non expired cert with the given subject in the directory cert store and return the token using (DirectoryCertificateStore store = new DirectoryCertificateStore()) { store.Open(storePath); X509CertificateCollection certificates = await store.Enumerate(); foreach (X509Certificate2 cert in certificates) { if ((token = CheckForToken(cert, name)) != null) { return(token); } } } break; } case CertificateStoreType.X509Store: { // search a non expired cert with the given subject in the X509 cert store and return the token using (X509Store store = new X509Store(storePath, StoreLocation.CurrentUser)) { store.Open(OpenFlags.ReadOnly); foreach (X509Certificate2 cert in store.Certificates) { if ((token = CheckForToken(cert, name)) != null) { return(token); } } } break; } default: { throw new Exception($"The requested store type '{storeType}' is not supported. Please change."); } } return(null); }
/// <summary> /// Ctor of the store, creates the random path name in a OS temp folder. /// </summary> private TemporaryCertValidator(bool rejectedStore) { // pki directory root for test runs. m_pkiRoot = Path.GetTempPath() + Path.GetRandomFileName() + Path.DirectorySeparatorChar; m_issuerStore = new DirectoryCertificateStore(); m_issuerStore.Open(m_pkiRoot + "issuer"); m_trustedStore = new DirectoryCertificateStore(); m_trustedStore.Open(m_pkiRoot + "trusted"); if (rejectedStore) { m_rejectedStore = new DirectoryCertificateStore(); m_rejectedStore.Open(m_pkiRoot + "rejected"); } }
/// <summary> /// Creates a self signed application instance certificate. /// </summary> /// <param name="storeType">Type of certificate store (Directory) <see cref="CertificateStoreType"/>.</param> /// <param name="storePath">The store path (syntax depends on storeType).</param> /// <param name="password">The password to use to protect the certificate.</param> /// <param name="applicationUri">The application uri (created if not specified).</param> /// <param name="applicationName">Name of the application (optional if subjectName is specified).</param> /// <param name="subjectName">The subject used to create the certificate (optional if applicationName is specified).</param> /// <param name="domainNames">The domain names that can be used to access the server machine (defaults to local computer name if not specified).</param> /// <param name="keySize">Size of the key (1024, 2048 or 4096).</param> /// <param name="startTime">The start time.</param> /// <param name="lifetimeInMonths">The lifetime of the key in months.</param> /// <param name="hashSizeInBits">The hash size in bits.</param> /// <param name="isCA">if set to <c>true</c> then a CA certificate is created.</param> /// <param name="issuerCAKeyCert">The CA cert with the CA private key.</param> /// <returns>The certificate with a private key.</returns> public static X509Certificate2 CreateCertificate( string storeType, string storePath, string password, string applicationUri, string applicationName, string subjectName, IList <String> domainNames, ushort keySize, DateTime startTime, ushort lifetimeInMonths, ushort hashSizeInBits, bool isCA, X509Certificate2 issuerCAKeyCert) { if (issuerCAKeyCert != null) { if (!issuerCAKeyCert.HasPrivateKey) { throw new NotSupportedException("Cannot sign with a CA certificate without a private key."); } } // set default values. X509Name subjectDN = SetSuitableDefaults( ref applicationUri, ref applicationName, ref subjectName, ref domainNames, ref keySize, ref lifetimeInMonths, isCA); using (var cfrg = new CertificateFactoryRandomGenerator()) { // cert generators SecureRandom random = new SecureRandom(cfrg); X509V3CertificateGenerator cg = new X509V3CertificateGenerator(); // Serial Number BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random); cg.SetSerialNumber(serialNumber); X509Name issuerDN = null; if (issuerCAKeyCert != null) { issuerDN = new X509Name(true, issuerCAKeyCert.Subject.Replace("S=", "ST=")); } else { // self signed issuerDN = subjectDN; } cg.SetIssuerDN(issuerDN); cg.SetSubjectDN(subjectDN); // valid for cg.SetNotBefore(startTime); cg.SetNotAfter(startTime.AddMonths(lifetimeInMonths)); // Private/Public Key AsymmetricCipherKeyPair subjectKeyPair; var keyGenerationParameters = new KeyGenerationParameters(random, keySize); var keyPairGenerator = new RsaKeyPairGenerator(); keyPairGenerator.Init(keyGenerationParameters); subjectKeyPair = keyPairGenerator.GenerateKeyPair(); cg.SetPublicKey(subjectKeyPair.Public); // add extensions // Subject key identifier cg.AddExtension(X509Extensions.SubjectKeyIdentifier.Id, false, new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(subjectKeyPair.Public))); // Basic constraints cg.AddExtension(X509Extensions.BasicConstraints.Id, true, new BasicConstraints(isCA)); // Authority Key identifier var issuerKeyPair = subjectKeyPair; var issuerSerialNumber = serialNumber; cg.AddExtension(X509Extensions.AuthorityKeyIdentifier.Id, false, new AuthorityKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(subjectKeyPair.Public), new GeneralNames(new GeneralName(issuerDN)), issuerSerialNumber)); if (!isCA) { // Key usage cg.AddExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.DataEncipherment | KeyUsage.DigitalSignature | KeyUsage.NonRepudiation | KeyUsage.KeyCertSign | KeyUsage.KeyEncipherment)); // Extended Key usage cg.AddExtension(X509Extensions.ExtendedKeyUsage, true, new ExtendedKeyUsage(new List <DerObjectIdentifier>() { new DerObjectIdentifier("1.3.6.1.5.5.7.3.1"), // server auth new DerObjectIdentifier("1.3.6.1.5.5.7.3.2"), // client auth })); // subject alternate name cg.AddExtension(X509Extensions.SubjectAlternativeName, false, new GeneralNames(new GeneralName[] { new GeneralName(GeneralName.UniformResourceIdentifier, applicationUri), new GeneralName(GeneralName.DnsName, domainNames[0]) })); } else { // Key usage CA cg.AddExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.CrlSign | KeyUsage.DigitalSignature | KeyUsage.KeyCertSign)); } // sign certificate AsymmetricKeyParameter privateKey = null; if (issuerCAKeyCert != null) { using (RSA rsa = issuerCAKeyCert.GetRSAPrivateKey()) { RSAParameters rsaParams = rsa.ExportParameters(true); RsaPrivateCrtKeyParameters keyParams = new RsaPrivateCrtKeyParameters( new BigInteger(1, rsaParams.Modulus), new BigInteger(1, rsaParams.Exponent), new BigInteger(1, rsaParams.D), new BigInteger(1, rsaParams.P), new BigInteger(1, rsaParams.Q), new BigInteger(1, rsaParams.DP), new BigInteger(1, rsaParams.DQ), new BigInteger(1, rsaParams.InverseQ)); privateKey = keyParams; } } else { privateKey = subjectKeyPair.Private; } ISignatureFactory signatureFactory = new Asn1SignatureFactory((hashSizeInBits < 256) ? "SHA1WITHRSA" : "SHA256WITHRSA", privateKey, random); Org.BouncyCastle.X509.X509Certificate x509 = cg.Generate(signatureFactory); // create pkcs12 store for cert and private key X509Certificate2 certificate = null; using (MemoryStream pfxData = new MemoryStream()) { Pkcs12Store pkcsStore = new Pkcs12StoreBuilder().Build(); X509CertificateEntry[] chain = new X509CertificateEntry[1]; string passcode = Guid.NewGuid().ToString(); chain[0] = new X509CertificateEntry(x509); pkcsStore.SetKeyEntry(applicationName, new AsymmetricKeyEntry(subjectKeyPair.Private), chain); pkcsStore.Save(pfxData, passcode.ToCharArray(), random); // merge into X509Certificate2 certificate = CreateCertificateFromPKCS12(pfxData.ToArray(), passcode); } Utils.Trace(Utils.TraceMasks.Security, "Created new certificate: {0}", certificate.Thumbprint); // add cert to the store. if (!String.IsNullOrEmpty(storePath)) { ICertificateStore store = null; if (storeType == CertificateStoreType.X509Store) { store = new X509CertificateStore(); } else if (storeType == CertificateStoreType.Directory) { store = new DirectoryCertificateStore(); } else { throw new ArgumentException("Invalid store type"); } store.Open(storePath); store.Add(certificate, password); store.Close(); store.Dispose(); } // note: this cert has a private key! return(certificate); } }
/// <summary> /// Creates a cert with the connectionstring (token) and stores it in the given cert store. /// </summary> public async static Task WriteAsync(string name, string connectionString, string storeType, string storePath) { if (string.IsNullOrEmpty(connectionString)) { throw new ArgumentException("Token not found in X509Store and no new token provided!"); } SecureRandom random = new SecureRandom(); KeyGenerationParameters keyGenerationParameters = new KeyGenerationParameters(random, 2048); RsaKeyPairGenerator keyPairGenerator = new RsaKeyPairGenerator(); keyPairGenerator.Init(keyGenerationParameters); AsymmetricCipherKeyPair keys = keyPairGenerator.GenerateKeyPair(); ArrayList nameOids = new ArrayList(); nameOids.Add(X509Name.CN); ArrayList nameValues = new ArrayList(); nameValues.Add(name); X509Name subjectDN = new X509Name(nameOids, nameValues); X509Name issuerDN = subjectDN; X509V3CertificateGenerator cg = new X509V3CertificateGenerator(); cg.SetSerialNumber(BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random)); cg.SetIssuerDN(issuerDN); cg.SetSubjectDN(subjectDN); cg.SetNotBefore(DateTime.Now); cg.SetNotAfter(DateTime.Now.AddMonths(12)); cg.SetPublicKey(keys.Public); cg.AddExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.DataEncipherment)); // encrypt the token with the public key so only the owner of the assoc. private key can decrypt it and // "hide" it in the instruction code cert extension RSA rsa = RSA.Create(); RSAParameters rsaParams = new RSAParameters(); RsaKeyParameters keyParams = (RsaKeyParameters)keys.Public; rsaParams.Modulus = new byte[keyParams.Modulus.ToByteArrayUnsigned().Length]; keyParams.Modulus.ToByteArrayUnsigned().CopyTo(rsaParams.Modulus, 0); rsaParams.Exponent = new byte[keyParams.Exponent.ToByteArrayUnsigned().Length]; keyParams.Exponent.ToByteArrayUnsigned().CopyTo(rsaParams.Exponent, 0); rsa.ImportParameters(rsaParams); if (rsa != null) { byte[] bytes = rsa.Encrypt(Encoding.ASCII.GetBytes(connectionString), RSAEncryptionPadding.OaepSHA1); if (bytes != null) { cg.AddExtension(X509Extensions.InstructionCode, false, bytes); } else { RsaUtils.RSADispose(rsa); throw new CryptographicException("Can not encrypt IoTHub security token using generated public key!"); } } RsaUtils.RSADispose(rsa); // sign the cert with the private key ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA256WITHRSA", keys.Private, random); Org.BouncyCastle.X509.X509Certificate x509 = cg.Generate(signatureFactory); // create a PKCS12 store for the cert and its private key X509Certificate2 certificate = null; using (MemoryStream pfxData = new MemoryStream()) { Pkcs12StoreBuilder builder = new Pkcs12StoreBuilder(); builder.SetUseDerEncoding(true); Pkcs12Store pkcsStore = builder.Build(); X509CertificateEntry[] chain = new X509CertificateEntry[1]; string passcode = Guid.NewGuid().ToString(); chain[0] = new X509CertificateEntry(x509); pkcsStore.SetKeyEntry(name, new AsymmetricKeyEntry(keys.Private), chain); pkcsStore.Save(pfxData, passcode.ToCharArray(), random); // create X509Certificate2 object from PKCS12 file certificate = CertificateFactory.CreateCertificateFromPKCS12(pfxData.ToArray(), passcode); // handle each store type differently switch (storeType) { case CertificateStoreType.Directory: { // Add to DirectoryStore using (DirectoryCertificateStore store = new DirectoryCertificateStore()) { store.Open(storePath); X509CertificateCollection certificates = await store.Enumerate(); // remove any existing cert with our name from the store foreach (X509Certificate2 cert in certificates) { if (cert.SubjectName.Decode(X500DistinguishedNameFlags.None | X500DistinguishedNameFlags.DoNotUseQuotes).Equals("CN=" + name, StringComparison.OrdinalIgnoreCase)) { await store.Delete(cert.Thumbprint); } } // add new one await store.Add(certificate); } break; } case CertificateStoreType.X509Store: { // Add to X509Store using (X509Store store = new X509Store(storePath, StoreLocation.CurrentUser)) { store.Open(OpenFlags.ReadWrite); // remove any existing cert with our name from the store foreach (X509Certificate2 cert in store.Certificates) { if (cert.SubjectName.Decode(X500DistinguishedNameFlags.None | X500DistinguishedNameFlags.DoNotUseQuotes).Equals("CN=" + name, StringComparison.OrdinalIgnoreCase)) { store.Remove(cert); } } // add new cert to store try { store.Add(certificate); } catch (Exception e) { throw new Exception($"Not able to add cert to the requested store type '{storeType}' (exception message: '{e.Message}'."); } } break; } default: { throw new Exception($"The requested store type '{storeType}' is not supported. Please change."); } } return; } }
protected void OneTimeSetUp() { // set max RSA key size and max SHA-2 hash size ushort keySize = 4096; ushort hashSize = 512; // pki directory root for test runs. m_pkiRoot = "%LocalApplicationData%/OPC/CertValidatorTest/" + ((DateTime.UtcNow.Ticks / 10000) % 3600000).ToString() + "/"; m_issuerStore = new DirectoryCertificateStore(); m_issuerStore.Open(m_pkiRoot + "issuer"); m_trustedStore = new DirectoryCertificateStore(); m_trustedStore.Open(m_pkiRoot + "trusted"); // good applications test set var appTestDataGenerator = new ApplicationTestDataGenerator(1); m_goodApplicationTestSet = appTestDataGenerator.ApplicationTestSet(kGoodApplicationsTestCount); // create all certs and CRL m_caChain = new X509Certificate2[kCaChainCount]; m_caDupeChain = new X509Certificate2[kCaChainCount]; m_caAllSameIssuerChain = new X509Certificate2[kCaChainCount]; m_crlChain = new X509CRL[kCaChainCount]; m_crlDupeChain = new X509CRL[kCaChainCount]; m_crlRevokedChain = new X509CRL[kCaChainCount]; m_appCerts = new X509Certificate2Collection(); m_appSelfSignedCerts = new X509Certificate2Collection(); DateTime rootCABaseTime = DateTime.UtcNow; rootCABaseTime = new DateTime(rootCABaseTime.Year - 1, 1, 1); var rootCert = CertificateFactory.CreateCertificate( null, null, null, null, null, "CN=Root CA Test Cert", null, keySize, rootCABaseTime, 25 * 12, hashSize, true, pathLengthConstraint: -1); m_caChain[0] = rootCert; m_crlChain[0] = CertificateFactory.RevokeCertificate(rootCert, null, null); m_caDupeChain[0] = CertificateFactory.CreateCertificate( null, null, null, null, null, "CN=Root CA Test Cert", null, keySize, rootCABaseTime, 25 * 12, hashSize, true, pathLengthConstraint: -1); m_crlDupeChain[0] = CertificateFactory.RevokeCertificate(m_caDupeChain[0], null, null); m_crlRevokedChain[0] = null; var signingCert = rootCert; DateTime subCABaseTime = DateTime.UtcNow; subCABaseTime = new DateTime(subCABaseTime.Year, subCABaseTime.Month, subCABaseTime.Day); for (int i = 1; i < kCaChainCount; i++) { if (keySize > 2048) { keySize -= 1024; } if (hashSize > 256) { hashSize -= 128; } var subject = $"CN=Sub CA {i} Test Cert"; var subCACert = CertificateFactory.CreateCertificate( null, null, null, null, null, subject, null, keySize, subCABaseTime, 5 * 12, hashSize, true, signingCert, pathLengthConstraint: kCaChainCount - 1 - i); m_caChain[i] = subCACert; m_crlChain[i] = CertificateFactory.RevokeCertificate(subCACert, null, null, subCABaseTime, subCABaseTime + TimeSpan.FromDays(10)); var subCADupeCert = CertificateFactory.CreateCertificate( null, null, null, null, null, subject, null, keySize, subCABaseTime, 5 * 12, hashSize, true, signingCert, pathLengthConstraint: kCaChainCount - 1 - i); m_caDupeChain[i] = subCADupeCert; m_crlDupeChain[i] = CertificateFactory.RevokeCertificate(subCADupeCert, null, null, subCABaseTime, subCABaseTime + TimeSpan.FromDays(10)); m_crlRevokedChain[i] = null; signingCert = subCACert; } // create a CRL with a revoked Sub CA for (int i = 0; i < kCaChainCount - 1; i++) { m_crlRevokedChain[i] = CertificateFactory.RevokeCertificate( m_caChain[i], new List <X509CRL>() { m_crlChain[i] }, new X509Certificate2Collection { m_caChain[i + 1] }); } // create self signed app certs DateTime appBaseTime = DateTime.UtcNow - TimeSpan.FromDays(1); foreach (var app in m_goodApplicationTestSet) { var subject = app.Subject; var appCert = CertificateFactory.CreateCertificate( null, null, null, app.ApplicationUri, app.ApplicationName, subject, app.DomainNames, CertificateFactory.DefaultKeySize, appBaseTime, 2 * 12, CertificateFactory.DefaultHashSize); m_appSelfSignedCerts.Add(appCert); } // create signed app certs foreach (var app in m_goodApplicationTestSet) { var subject = app.Subject; var appCert = CertificateFactory.CreateCertificate( null, null, null, app.ApplicationUri, app.ApplicationName, subject, app.DomainNames, CertificateFactory.DefaultKeySize, appBaseTime, 2 * 12, CertificateFactory.DefaultHashSize, false, signingCert); app.Certificate = appCert.RawData; m_appCerts.Add(appCert); } // create a CRL with all apps revoked m_crlRevokedChain[kCaChainCount - 1] = CertificateFactory.RevokeCertificate( m_caChain[kCaChainCount - 1], new List <X509CRL>() { m_crlChain[kCaChainCount - 1] }, m_appCerts); }
protected void OneTimeSetUp() { // set max RSA key size and max SHA-2 hash size ushort keySize = 4096; ushort hashSize = 512; // pki directory root for test runs. m_pkiRoot = "%LocalApplicationData%/OPC/CertValidatorTest/" + ((DateTime.UtcNow.Ticks / 10000) % 3600000).ToString() + "/"; m_issuerStore = new DirectoryCertificateStore(); m_issuerStore.Open(m_pkiRoot + "issuer"); m_trustedStore = new DirectoryCertificateStore(); m_trustedStore.Open(m_pkiRoot + "trusted"); // good applications test set var appTestDataGenerator = new ApplicationTestDataGenerator(1); m_goodApplicationTestSet = appTestDataGenerator.ApplicationTestSet(kGoodApplicationsTestCount); // create all certs and CRL m_caChain = new X509Certificate2[kCaChainCount]; m_caDupeChain = new X509Certificate2[kCaChainCount]; m_crlChain = new X509CRL[kCaChainCount]; m_crlDupeChain = new X509CRL[kCaChainCount]; m_crlRevokedChain = new X509CRL[kCaChainCount]; m_appCerts = new X509Certificate2Collection(); m_appSelfSignedCerts = new X509Certificate2Collection(); DateTime rootCABaseTime = DateTime.UtcNow; rootCABaseTime = new DateTime(rootCABaseTime.Year - 1, 1, 1); var rootCert = CertificateFactory.CreateCertificate(RootCASubject) .SetNotBefore(rootCABaseTime) .SetLifeTime(25 * 12) .SetCAConstraint() .SetHashAlgorithm(CertificateFactory.GetRSAHashAlgorithmName(hashSize)) .SetRSAKeySize(keySize) .CreateForRSA(); m_caChain[0] = rootCert; m_crlChain[0] = CertificateFactory.RevokeCertificate(rootCert, null, null); // to save time, the dupe chain uses just the default key size/hash m_caDupeChain[0] = CertificateFactory.CreateCertificate(RootCASubject) .SetNotBefore(rootCABaseTime) .SetLifeTime(25 * 12) .SetCAConstraint() .CreateForRSA(); m_crlDupeChain[0] = CertificateFactory.RevokeCertificate(m_caDupeChain[0], null, null); m_crlRevokedChain[0] = null; var signingCert = rootCert; DateTime subCABaseTime = DateTime.UtcNow; subCABaseTime = new DateTime(subCABaseTime.Year, subCABaseTime.Month, subCABaseTime.Day, 0, 0, 0, DateTimeKind.Utc); for (int i = 1; i < kCaChainCount; i++) { if (keySize > 2048) { keySize -= 1024; } if (hashSize > 256) { hashSize -= 128; } var subject = $"CN=Sub CA {i} Test Cert"; var subCACert = CertificateFactory.CreateCertificate(subject) .SetNotBefore(subCABaseTime) .SetLifeTime(5 * 12) .SetHashAlgorithm(CertificateFactory.GetRSAHashAlgorithmName(hashSize)) .SetCAConstraint(kCaChainCount - 1 - i) .SetIssuer(signingCert) .SetRSAKeySize(keySize) .CreateForRSA(); m_caChain[i] = subCACert; m_crlChain[i] = CertificateFactory.RevokeCertificate(subCACert, null, null, subCABaseTime, subCABaseTime + TimeSpan.FromDays(10)); var subCADupeCert = CertificateFactory.CreateCertificate(subject) .SetNotBefore(subCABaseTime) .SetLifeTime(5 * 12) .SetCAConstraint(kCaChainCount - 1 - i) .SetIssuer(signingCert) .CreateForRSA(); m_caDupeChain[i] = subCADupeCert; m_crlDupeChain[i] = CertificateFactory.RevokeCertificate(subCADupeCert, null, null, subCABaseTime, subCABaseTime + TimeSpan.FromDays(10)); m_crlRevokedChain[i] = null; signingCert = subCACert; } // create a CRL with a revoked Sub CA for (int i = 0; i < kCaChainCount - 1; i++) { m_crlRevokedChain[i] = CertificateFactory.RevokeCertificate( m_caChain[i], new List <X509CRL>() { m_crlChain[i] }, new X509Certificate2Collection { m_caChain[i + 1] }); } // create self signed app certs foreach (var app in m_goodApplicationTestSet) { var subject = app.Subject; var appCert = CertificateFactory.CreateCertificate( app.ApplicationUri, app.ApplicationName, subject, app.DomainNames) .CreateForRSA(); m_appSelfSignedCerts.Add(appCert); } // create signed app certs foreach (var app in m_goodApplicationTestSet) { var subject = app.Subject; var appCert = CertificateFactory.CreateCertificate( app.ApplicationUri, app.ApplicationName, subject, app.DomainNames) .SetIssuer(signingCert) .CreateForRSA(); app.Certificate = appCert.RawData; m_appCerts.Add(appCert); } // create a CRL with all apps revoked m_crlRevokedChain[kCaChainCount - 1] = CertificateFactory.RevokeCertificate( m_caChain[kCaChainCount - 1], new List <X509CRL>() { m_crlChain[kCaChainCount - 1] }, m_appCerts); }