public CreatePrivateCertificateResult CreateCertificateWithPrivateKey(CreatePrivateCertificateModel model, ClaimsPrincipal user)
        {
            model.RequestDate = DateTime.Now;

            KeyUsage keyUsage = dataTransformation.ParseKeyUsage(model.KeyUsage);

            AdcsTemplate template = templateLogic.DiscoverTemplate(model.CipherAlgorithm, model.Provider, keyUsage);

            if (!templateLogic.ValidateTemplateWithRequest(model, template))
            {
                throw new AdcsTemplateValidationException("Certificate request does not meet the requirements of the certificate template");
            }

            if (authorizationLogic.IsAuthorized(template, user))
            {
                CertificateRequest csr = certificateProvider.CreateCsrKeyPair(dataTransformation.NewCertificateSubjectFromModel(model), model.CipherAlgorithm, model.KeySize, model.Provider, SigningRequestProtocol.Pkcs10);

                MicrosoftCertificateAuthority ca = configurationRepository.GetPrivateCertificateAuthority(model.HashAlgorithm);

                CertificateAuthorityRequestResponse response = ca.Sign(csr, template.Name, template.KeyUsage);

                CreatePrivateCertificateResult result = ProcessCertificateAuthorityResponse(model, response, csr.Subject, user);

                this.Audit(result, user);

                return(result);
            }
            else
            {
                return(ProcessNewPendingCertificateWorkflow(model));
            }
        }
        public CreatePrivateCertificateResult IssuePendingCertificate(Guid id, ClaimsPrincipal user)
        {
            PendingCertificate pendingCertificate = certificateRepository.Get <PendingCertificate>(id);

            KeyUsage keyUsage = dataTransformation.ParseKeyUsage(pendingCertificate.KeyUsage);

            AdcsTemplate template = templateLogic.DiscoverTemplate(pendingCertificate.CipherAlgorithm, pendingCertificate.Provider, keyUsage);

            if (authorizationLogic.IsAuthorized(template, user))
            {
                CertificateRequest csr = certificateProvider.CreateCsrKeyPair(dataTransformation.NewCertificateSubjectFromModel(pendingCertificate), pendingCertificate.CipherAlgorithm, pendingCertificate.KeySize, pendingCertificate.Provider, SigningRequestProtocol.Pkcs10);

                MicrosoftCertificateAuthority ca = configurationRepository.GetPrivateCertificateAuthority(pendingCertificate.HashAlgorithm);

                CertificateAuthorityRequestResponse response = ca.Sign(csr, template.Name, template.KeyUsage);

                CreatePrivateCertificateResult result = ProcessCertificateAuthorityResponse(pendingCertificate, response, csr.Subject, user);

                certificateRepository.Delete <PendingCertificate>(id);

                return(result);
            }
            else
            {
                throw new UnauthorizedAccessException("Current user is not authorized to issue pending certificates");
            }
        }
        public void PrivateCertificateProcessing_CreateCertificate_CngRsa2048_ClientServerAuth_ReturnedX509Certificate2HasClientServerAuthKeyUsage()
        {
            KeyUsage expected = KeyUsage.ServerAuthentication | KeyUsage.ClientAuthentication;

            CreatePrivateCertificateModel model = new CreatePrivateCertificateModel()
            {
                CipherAlgorithm            = CipherAlgorithm.RSA,
                KeyUsage                   = expected.ToString(),
                HashAlgorithm              = HashAlgorithm.SHA256,
                KeySize                    = 2048,
                Provider                   = WindowsApi.Cng,
                SubjectAlternativeNamesRaw = "integrationtestdomain.com,integrationtestdomain",
                SubjectCity                = "Seattle",
                SubjectCommonName          = "integrationtestdomain",
                SubjectCountry             = "US",
                SubjectDepartment          = "Engineering",
                SubjectState               = "WA",
                SubjectOrganization        = "IntegrationTestingCorp"
            };


            PrivateCertificateProcessing   processor = new PrivateCertificateProcessing(certDb, configDb, certProvider, GetAuthorizationLogic_Allow(), templateLogic, GetAuditLogic());
            CreatePrivateCertificateResult result    = processor.CreateCertificateWithPrivateKey(model, user.Object);

            X509Certificate2 cert = new X509Certificate2(result.PfxByte, result.Password);

            KeyUsage actualKeyUsage = x509Normalization.GetKeyUsage(cert);

            Assert.AreEqual(expected, actualKeyUsage);
        }
        public void PrivateCertificateProcessing_CreateCertificate_CngRsa2048_ClientServerAuth_Success()
        {
            KeyUsage keyUsage = KeyUsage.ServerAuthentication | KeyUsage.ClientAuthentication;
            CreatePrivateCertificateModel model = new CreatePrivateCertificateModel()
            {
                CipherAlgorithm            = CipherAlgorithm.RSA,
                KeyUsage                   = keyUsage.ToString(),
                HashAlgorithm              = HashAlgorithm.SHA256,
                KeySize                    = 2048,
                Provider                   = WindowsApi.Cng,
                SubjectAlternativeNamesRaw = "integrationtestdomain.com,integrationtestdomain",
                SubjectCity                = "Seattle",
                SubjectCommonName          = "integrationtestdomain",
                SubjectCountry             = "US",
                SubjectDepartment          = "Engineering",
                SubjectState               = "WA",
                SubjectOrganization        = "IntegrationTestingCorp"
            };


            PrivateCertificateProcessing   processor = new PrivateCertificateProcessing(certDb, configDb, certProvider, GetAuthorizationLogic_Allow(), templateLogic, GetAuditLogic());
            CreatePrivateCertificateResult result    = processor.CreateCertificateWithPrivateKey(model, user.Object);

            Assert.AreEqual(PrivateCertificateRequestStatus.Success, result.Status);
        }
        public JsonResult CreateCertificate(CreatePrivateCertificateModel model)
        {
            PrivateCertificateProcessing processor = new PrivateCertificateProcessing(certificateRepository, configurationRepository, certificateProvider, authorizationLogic, templateLogic, audit);

            CreatePrivateCertificateResult result = processor.CreateCertificateWithPrivateKey(model, User);

            return(http.RespondSuccess(result));
        }
        public JsonResult IssuePendingCertificate(Guid id)
        {
            PrivateCertificateProcessing processor = new PrivateCertificateProcessing(certificateRepository, configurationRepository, certificateProvider, authorizationLogic, templateLogic, audit);

            CreatePrivateCertificateResult result = processor.IssuePendingCertificate(id, User);

            return(http.RespondSuccess(result));
        }
        private CreatePrivateCertificateResult ProcessNewPendingCertificateWorkflow(CreatePrivateCertificateModel model)
        {
            CreatePrivateCertificateResult result = new CreatePrivateCertificateResult(PrivateCertificateRequestStatus.Pending, Guid.NewGuid());

            PendingCertificate pendingCertificate = new PendingCertificate(model);

            certificateRepository.Insert <PendingCertificate>(pendingCertificate);

            return(result);
        }
        private CreatePrivateCertificateResult ProcessCertificateAuthoritySuccessResponse(ICertificateRequestPublicPrivateKeyPair model, CertificateAuthorityRequestResponse response, CertificateSubject subject, ClaimsPrincipal user)
        {
            string           nonce    = secrets.NewSecretBase64(16);
            string           password = secrets.NewSecret(64);
            X509Certificate2 cert     = certificateProvider.InstallIssuedCertificate(response.IssuedCertificate);

            SetPrivateKeyFileSystemAccess(model, cert, user);

            byte[] certContent = cert.Export(X509ContentType.Pfx, password);

            CreatePrivateCertificateResult result = new CreatePrivateCertificateResult()
            {
                Password   = password,
                Pfx        = Convert.ToBase64String(certContent),
                Status     = PrivateCertificateRequestStatus.Success,
                Thumbprint = cert.Thumbprint,
                Id         = Guid.NewGuid(),
            };

            List <AccessControlEntry> defaultAcl = authorizationLogic.GetDefaultCertificateAcl(user);

            Certificate storedCert = new Certificate()
            {
                Id          = result.Id,
                Thumbprint  = cert.Thumbprint,
                PfxPassword = cipher.Encrypt(password, nonce),
                WindowsApi  = model.Provider,
                Content     = certContent,
                CertificateStorageFormat = CertificateStorageFormat.Pfx,
                HashAlgorithm            = model.HashAlgorithm,
                CipherAlgorithm          = model.CipherAlgorithm,
                DisplayName   = model.SubjectCommonName,
                HasPrivateKey = true,
                ValidTo       = cert.NotAfter,
                ValidFrom     = cert.NotBefore,
                KeySize       = model.KeySize,
                KeyUsage      = dataTransformation.ParseKeyUsage(model.KeyUsage),
                Subject       = subject,
                Acl           = defaultAcl,
                PasswordNonce = nonce,
                ContentDigest = hashProvider.ComputeHash(certContent)
            };

            certificateRepository.Insert(storedCert);

            return(result);
        }
        private void StartIISCertificateRenewal(NodeCredentialed node, ManagedCertificate managedCertificate, ClaimsPrincipal user)
        {
            //Collection<HostIISCertificateEntity> result = null;
            try
            {
                X509Certificate2 cert = new X509Certificate2(Convert.FromBase64String(managedCertificate.X509Content));

                CreatePrivateCertificateModel entity = new CreatePrivateCertificateModel(cert);

                entity.KeyUsage = dataTransformation.GetEkuStringFromX509Certificate2(cert);

                CreatePrivateCertificateResult newCert = privateCertificateProcessing.CreateCertificateWithPrivateKey(entity, user);

                if (newCert.Status != PrivateCertificateRequestStatus.Success)
                {
                    throw new CertificateAuthorityDeniedRequestException("Certificate request could not be processed");
                }

                DownloadPfxCertificateEntity pfx = certificateManagement.GetPfxCertificateContent(newCert.Id);

                string password = certificateManagement.GetCertificatePassword(newCert.Id, user).DecryptedPassword;

                Dictionary <string, object> cmdletParams = new Dictionary <string, object>()
                {
                    { "ComputerName", node.Hostname },
                    { "Credential", powershell.NewPSCredential(node.CredentialContext.Username, node.CredentialContext.Password) },
                    { "CertificateContent", Convert.ToBase64String(pfx.Content) },
                    { "CertificateKey", password },
                    { "BindingPath", managedCertificate.PSPath }
                };

                object result = powershell.InvokeScriptAsync <object>(iisCertificateRenewal, cmdletParams, user);
                this.InvokeIISCertificateDiscovery(node.Id, user);
                return;
                //result = powershell.InvokeScriptAsync<HostIISCertificateEntity>(hostIisDiscoveryScript, cmdletParams, user);
                //this.RecieveIISCertificateDiscoveryResult(result, node);
            }
            catch (Exception ex)
            {
                string msg = string.Format("An error occured while starting the certificate deployment job {0}", ex.ToString());
                auditLogic.LogOpsError(user, node.Id.ToString(), EventCategory.PowershellJob, msg);
            }
        }
        private void Audit(CreatePrivateCertificateResult result, ClaimsPrincipal user)
        {
            switch (result.Status)
            {
            case PrivateCertificateRequestStatus.Success:
                audit.LogOpsSuccess(user, result.Thumbprint, EventCategory.CertificateIssuance, "Certificate was successfully issued");
                break;

            case PrivateCertificateRequestStatus.Pending:
                audit.LogOpsSuccess(user, result.Thumbprint, EventCategory.CertificateIssuance, "Certificate is pending issuance");
                break;

            case PrivateCertificateRequestStatus.Error:
                audit.LogOpsError(user, string.Empty, EventCategory.CertificateIssuance, string.Format("Failed to issue certificate", result.Message));
                break;

            default:
                audit.LogOpsError(user, string.Empty, EventCategory.CertificateIssuance, string.Format("Failed to issue certificate", result.Message));
                break;
            }
        }