private ICertificateStore CreateStore(string storePath) { ICertificateStore store = CertificateStoreIdentifier.CreateStore(CertificateStoreIdentifier.DetermineStoreType(storePath)); store.Open(storePath); return(store); }
public async Task <X509CertificateCollection> KeyVaultSigningRequestAsync() { Skip.If(!_fixture.KeyVaultInitOk); X509CertificateCollection certCollection = new X509CertificateCollection(); string[] groups = await _keyVault.GetCertificateGroupIds(); foreach (string group in groups) { var certificateGroupConfiguration = await _keyVault.GetCertificateGroupConfiguration(group); ApplicationTestData randomApp = _fixture.RandomGenerator.RandomApplicationTestData(); X509Certificate2 csrCertificate = CertificateFactory.CreateCertificate( null, null, null, randomApp.ApplicationRecord.ApplicationUri, null, randomApp.Subject, randomApp.DomainNames.ToArray(), certificateGroupConfiguration.DefaultCertificateKeySize, DateTime.UtcNow.AddDays(-10), certificateGroupConfiguration.DefaultCertificateLifetime, certificateGroupConfiguration.DefaultCertificateHashSize ); byte[] certificateRequest = CertificateFactory.CreateSigningRequest(csrCertificate, randomApp.DomainNames); X509Certificate2 newCert = await _keyVault.SigningRequestAsync( group, randomApp.ApplicationRecord.ApplicationUri, certificateRequest); // get issuer cert used for signing X509Certificate2Collection issuerCerts = await _keyVault.GetIssuerCACertificateChainAsync(group); #if WRITECERT // save cert for debugging using (ICertificateStore store = CertificateStoreIdentifier.CreateStore(CertificateStoreType.Directory)) { Assert.NotNull(store); store.Open("d:\\unittest"); await store.Add(newCert); foreach (var cert in issuerCerts) { await store.Add(cert); } } #endif Assert.NotNull(issuerCerts); Assert.True(issuerCerts.Count >= 1); X509TestUtils.VerifySignedApplicationCert(randomApp, newCert, issuerCerts); certCollection.Add(newCert); } return(certCollection); }
/// <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 = false, X509Certificate2 issuerCAKeyCert = null, byte[] publicKey = null) { if (issuerCAKeyCert != null) { if (!issuerCAKeyCert.HasPrivateKey) { throw new NotSupportedException("Cannot sign with a CA certificate without a private key."); } } if (publicKey != null && issuerCAKeyCert == null) { throw new NotSupportedException("Cannot use a public key without a CA certificate with a private key."); } // set default values. X509Name subjectDN = SetSuitableDefaults( ref applicationUri, ref applicationName, ref subjectName, ref domainNames, ref keySize, ref lifetimeInMonths); 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); // subject and issuer DN X509Name issuerDN = null; if (issuerCAKeyCert != null) { issuerDN = new CertificateFactoryX509Name(issuerCAKeyCert.Subject); } else { // self signed issuerDN = subjectDN; } cg.SetIssuerDN(issuerDN); cg.SetSubjectDN(subjectDN); // valid for cg.SetNotBefore(startTime); cg.SetNotAfter(startTime.AddMonths(lifetimeInMonths)); // set Private/Public Key AsymmetricKeyParameter subjectPublicKey; AsymmetricKeyParameter subjectPrivateKey; if (publicKey == null) { var keyGenerationParameters = new KeyGenerationParameters(random, keySize); var keyPairGenerator = new RsaKeyPairGenerator(); keyPairGenerator.Init(keyGenerationParameters); AsymmetricCipherKeyPair subjectKeyPair = keyPairGenerator.GenerateKeyPair(); subjectPublicKey = subjectKeyPair.Public; subjectPrivateKey = subjectKeyPair.Private; } else { // special case, if a cert is signed by CA, the private key of the cert is not needed subjectPublicKey = PublicKeyFactory.CreateKey(publicKey); subjectPrivateKey = null; } cg.SetPublicKey(subjectPublicKey); // add extensions // Subject key identifier cg.AddExtension(X509Extensions.SubjectKeyIdentifier.Id, false, new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(subjectPublicKey))); // Basic constraints cg.AddExtension(X509Extensions.BasicConstraints.Id, true, new BasicConstraints(isCA)); // Authority Key identifier references the issuer cert or itself when self signed AsymmetricKeyParameter issuerPublicKey; BigInteger issuerSerialNumber; if (issuerCAKeyCert != null) { issuerPublicKey = GetPublicKeyParameter(issuerCAKeyCert); issuerSerialNumber = GetSerialNumber(issuerCAKeyCert); } else { issuerPublicKey = subjectPublicKey; issuerSerialNumber = serialNumber; } cg.AddExtension(X509Extensions.AuthorityKeyIdentifier.Id, false, new AuthorityKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(issuerPublicKey), 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 List <GeneralName> generalNames = new List <GeneralName>(); generalNames.Add(new GeneralName(GeneralName.UniformResourceIdentifier, applicationUri)); generalNames.AddRange(CreateSubjectAlternateNameDomains(domainNames)); cg.AddExtension(X509Extensions.SubjectAlternativeName, false, new GeneralNames(generalNames.ToArray())); } else { // Key usage CA cg.AddExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.CrlSign | KeyUsage.DigitalSignature | KeyUsage.KeyCertSign)); } // sign certificate AsymmetricKeyParameter signingKey; if (issuerCAKeyCert != null) { // signed by issuer signingKey = GetPrivateKeyParameter(issuerCAKeyCert); } else { // self signed signingKey = subjectPrivateKey; } ISignatureFactory signatureFactory = new Asn1SignatureFactory(GetRSAHashAlgorithm(hashSizeInBits), signingKey, random); Org.BouncyCastle.X509.X509Certificate x509 = cg.Generate(signatureFactory); // convert to X509Certificate2 X509Certificate2 certificate = null; if (subjectPrivateKey == null) { // create the cert without the private key certificate = new X509Certificate2(x509.GetEncoded()); } else { // note: this cert has a private key! certificate = CreateCertificateWithPrivateKey(x509, null, subjectPrivateKey, random); } Utils.Trace(Utils.TraceMasks.Security, "Created new certificate: {0}", certificate.Thumbprint); // add cert to the store. if (!String.IsNullOrEmpty(storePath) && !String.IsNullOrEmpty(storeType)) { using (ICertificateStore store = CertificateStoreIdentifier.CreateStore(storeType)) { if (store == null) { throw new ArgumentException("Invalid store type"); } store.Open(storePath); store.Add(certificate, password).Wait(); store.Close(); } } return(certificate); } }