public void Setup()
        {
            AdcsTemplate result = null;

            try
            {
                result = configDb.Get <AdcsTemplate>(x => x.Cipher == CipherAlgorithm.RSA && x.WindowsApi == WindowsApi.CryptoApi && x.KeyUsage == KeyUsage.ServerAuthentication).First();
                //result = configDb.GetAdcsTemplate(HashAlgorithm.SHA256, CipherAlgorithm.RSA, WindowsApi.CryptoApi, KeyUsage.ServerAuthentication);
            }
            catch
            {
                if (result == null)
                {
                    configDb.Insert <AdcsTemplate>(new AdcsTemplate()
                    {
                        WindowsApi = WindowsApi.CryptoApi,
                        Cipher     = CipherAlgorithm.RSA,
                        //Hash = HashAlgorithm.SHA256,
                        KeyUsage = KeyUsage.ServerAuthentication,
                        Name     = "ServerAuthentication-CapiRsa"
                    });
                }
            }
            ActiveDirectoryMetadata idp = configDb.GetAll <ActiveDirectoryMetadata>().FirstOrDefault();

            configDb.DropCollection <PrivateCertificateAuthorityConfig>();

            PrivateCertificateAuthorityConfig caConfig = new PrivateCertificateAuthorityConfig()
            {
                CommonName         = caCommonName,
                ServerName         = caServerName,
                HashAlgorithm      = HashAlgorithm.SHA256,
                IdentityProviderId = idp.Id
            };
        }
        public bool IsAuthorized(AdcsTemplate template, ClaimsPrincipal user)
        {
            if (template == null || template.RolesAllowedToIssue == null)
            {
                throw new ArgumentNullException(nameof(template));
            }

            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }

            if (template.RolesAllowedToIssue.Count < 1)
            {
                throw new UnauthorizedAccessException();
            }

            foreach (Guid roleId in template.RolesAllowedToIssue)
            {
                if (IncludesRole(user, roleId))
                {
                    return(true);
                }
            }

            return(false);
        }
        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 AdcsTemplate DiscoverTemplate(CipherAlgorithm cipher, WindowsApi api, KeyUsage keyUsage)
        {
            Expression <Func <AdcsTemplate, bool> > query = template => template.Cipher == cipher && template.WindowsApi == api && template.KeyUsage.ToString() == keyUsage.ToString();
            AdcsTemplate results = configurationRepository.Get <AdcsTemplate>(query).First();

            return(results);
        }
        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 ValidateTemplatePublishedActiveDirectory(AdcsTemplate template)
        {
            IEnumerable <ActiveDirectoryMetadata> metadataList = configurationRepository.GetAll <ActiveDirectoryMetadata>();

            if (metadataList == null)
            {
                throw new AdcsTemplateValidationException("There are no active directory domains configured.");
            }

            foreach (ActiveDirectoryMetadata metadata in metadataList)
            {
                List <AdcsCertificateTemplate> templates = this.GetActiveDirectoryTemplates(metadata);

                if (!templates.Where(x => x.Name == template.Name).Any())
                {
                    throw new AdcsTemplateValidationException("Adcs template is not published in Active Directory");
                }

                if (templates.Where(x => x.Name == template.Name).Count() > 1)
                {
                    throw new AdcsTemplateValidationException("Search for Adcs templates by name in Active Directory returned more than one result, this is not allowed");
                }

                AdcsCertificateTemplate adTemplate = templates.Where(x => x.Name == template.Name).First();


                if (template.WindowsApi != adTemplate.WindowsApi)
                {
                    string msg = string.Format("Certificate Manager Template Windows API does not match the template in active directory. AD shows {0}, CertificateManager requested {1}", adTemplate.WindowsApi, template.WindowsApi);
                    throw new AdcsTemplateValidationException(msg);
                }

                if (template.Cipher != adTemplate.Cipher)
                {
                    string msg = string.Format("Certificate Manager Template cipher algorithm does not match the template in active directory. AD shows {0}, CertificateManager requested {1}", adTemplate.Cipher, template.Cipher);
                    throw new AdcsTemplateValidationException(msg);
                }
                if (!adTemplate.AllowsClientProvidedSubject())
                {
                    throw new AdcsTemplateValidationException("Adcs template was found in Active Directory, but the template does not allow the client to specify the subject");
                }

                if (adTemplate.RequiresStrongKeyProtection())
                {
                    throw new AdcsTemplateValidationException("Adcs template in Active Directory requires strong key protection. Certificate Manager inplements strong key protection that is incompatible with Active Directory Certificate Services. ");
                }

                if (adTemplate.PendAllRequests())
                {
                    throw new AdcsTemplateValidationException("Issuance requires pending the certificate for manager approval. This is not compatible with Certificate Manager");
                }

                if (adTemplate.RequireUserInteraction())
                {
                    throw new AdcsTemplateValidationException("Issuance requires user interaction. This is not compatible with Certificate Manager");
                }
            }
        }
 public bool ValidateTemplateWithRequest(CreatePrivateCertificateModel model, AdcsTemplate template)
 {
     if (model.KeySize < template.MinimumKeySize)
     {
         return(false);
     }
     else
     {
         return(true);
     }
 }
        public AdcsTemplateGetModel GetTemplate(Guid id)
        {
            AdcsTemplate template = configurationRepository.Get <AdcsTemplate>(id);

            return(new AdcsTemplateGetModel()
            {
                Name = template.Name,
                Cipher = template.Cipher,
                KeyUsage = template.KeyUsage,
                WindowsApi = template.WindowsApi,
                Id = template.Id,
                RolesAllowedToIssueSelectView = GetSecrityRoleListView(template.RolesAllowedToIssue)
            });
        }
        public AdcsTemplate AddTemplate(string name, CipherAlgorithm cipher, KeyUsage keyUsage, WindowsApi api, List <Guid> rolesAllowedToIssue)
        {
            AdcsTemplate template = new AdcsTemplate()
            {
                Name                = name,
                Cipher              = cipher,
                KeyUsage            = keyUsage,
                WindowsApi          = api,
                RolesAllowedToIssue = rolesAllowedToIssue
            };

            configurationRepository.Insert <AdcsTemplate>(template);

            return(template);
        }
        public AdcsTemplateGetModel AddTemplate(AdcsTemplate template)
        {
            IEnumerable <PrivateCertificateAuthorityConfig> ca = configurationRepository.GetAll <PrivateCertificateAuthorityConfig>();

            if (ca == null)
            {
                throw new PrivateCertificateAuthorityDoesNotExistException("A certificate authority must exist before adding a template");
            }

            this.ValidateTemplatePublishedActiveDirectory(template);

            List <AdcsCertificateTemplate> templatesFromAllRealms = this.GetTemplateInAllActiveDirectoryRealms(template.Name);

            template.Id             = Guid.NewGuid();
            template.MinimumKeySize = templatesFromAllRealms.Select(x => x.MinimumKeySize).Max();
            configurationRepository.Insert <AdcsTemplate>(template);

            return(this.GetTemplate(template.Id));
        }
        public SignPrivateCertificateResult SignCertificate(SignPrivateCertificateModel model, ClaimsPrincipal user)
        {
            CertificateRequest csr = certificateProvider.InitializeFromEncodedCsr(model.EncodedCsr);

            AdcsTemplate template = templateLogic.DiscoverTemplate(csr.CipherAlgorithm, WindowsApi.Cng, KeyUsage.ServerAuthentication);

            if (authorizationLogic.IsAuthorized(template, user))
            {
                MicrosoftCertificateAuthority ca = configurationRepository.GetPrivateCertificateAuthority(model.HashAlgorithm);

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

                return(HandleCertificateAuthorityResponse(model, response, csr.Subject));
            }
            else
            {
                return(ProcessPendingSigningWorkflow(model));
            }
        }
        public AdcsTemplateGetModel UpdateTemplate(AdcsTemplateUpdateModel updateEntity)
        {
            if (updateEntity.Name == "error")
            {
                throw new PrivateCertificateAuthorityDoesNotExistException("A certificate authority must exist before adding a template");
            }

            AdcsTemplate template = configurationRepository.Get <AdcsTemplate>(updateEntity.Id);

            template.Name = updateEntity.Name;
            template.RolesAllowedToIssue = dataTransform.ParseGuidList(updateEntity.RolesAllowedToIssue);
            template.KeyUsage            = updateEntity.KeyUsage;
            template.WindowsApi          = updateEntity.WindowsApi;
            template.Cipher = updateEntity.Cipher;

            configurationRepository.Update <AdcsTemplate>(template);


            AdcsTemplateGetModel response = new AdcsTemplateGetModel();

            response.Name       = template.Name;
            response.Cipher     = template.Cipher;
            response.KeyUsage   = template.KeyUsage;
            response.WindowsApi = template.WindowsApi;
            response.Id         = template.Id;

            response.RolesAllowedToIssueSelectView = new List <SecurityRoleSelectView>();
            foreach (Guid roleId in template.RolesAllowedToIssue)
            {
                var role = configurationRepository.Get <SecurityRole>(roleId);

                response.RolesAllowedToIssueSelectView.Add(
                    new SecurityRoleSelectView()
                {
                    Id   = roleId,
                    Name = role.Name
                });
            }

            return(response);
        }
        public void Complete(InitialSetupConfigModel config)
        {
            ActiveDirectoryMetadata idp = idpLogic.Add(config.AdName, config.AdServer, config.AdSearchBase, config.AdServiceAccountUsername, config.AdServiceAccountPassword, config.AdUseAppPoolIdentity);

            certificateAuthorityConfigurationLogic.AddPrivateCertificateAuthority(config.AdcsServerName, config.AdcsCommonName, config.AdcsHashAlgorithm, idp.Id);
            AdcsTemplate           adcsTemplate    = templateLogic.AddTemplate(config.AdcsTemplateName, config.AdcsTemplateCipher, config.AdcsTemplateKeyUsage, config.AdcsTemplateWindowsApi, RoleManagementLogic.DefaultTemplateIssuerRoles);
            AuthenticablePrincipal emergencyAccess = localIdpLogic.InitializeEmergencyAccess(config.EmergencyAccessKey);
            AuthenticablePrincipal admin           = localIdpLogic.InitializeLocalAdministrator(config.LocalAdminPassword);

            authorizationLogic.InitializeScopes();
            roleManagement.InitializeRoles(new List <Guid>()
            {
                emergencyAccess.Id, admin.Id
            });

            AppConfig appConfig = new AppConfig()
            {
                EncryptionKey = config.EncryptionKey,
                Id            = Guid.NewGuid()
            };

            configurationRepository.SetAppConfig(appConfig);
        }
 public bool IsAuthorized(AdcsTemplate template, ClaimsPrincipal user)
 {
     return(true);
 }
 public JsonResult AddAdcsTemplate(AdcsTemplate template)
 {
     return(http.RespondSuccess(adcsTemplateLogic.AddTemplate(template)));
 }