Beispiel #1
0
        private Func <bool> PrepareChallengeResponse_TlsSni01(ILog log, ICertifiedServer iisManager, string domain, ManagedCertificate managedCertificate, PendingAuthorization pendingAuth)
        {
            var requestConfig = managedCertificate.RequestConfig;

            var tlsSniChallenge = pendingAuth.Challenges.FirstOrDefault(c => c.ChallengeType == SupportedChallengeTypes.CHALLENGE_TYPE_SNI);

            if (tlsSniChallenge == null)
            {
                log.Warning($"No tls-sni-01 challenge to complete for {managedCertificate.Name}. Request cannot continue.");
                return(() => false);
            }

            var sha256 = System.Security.Cryptography.SHA256.Create();

            var z = new byte[tlsSniChallenge.HashIterationCount][];

            // compute n sha256 hashes, where n=challengedata.iterationcount
            z[0] = sha256.ComputeHash(Encoding.UTF8.GetBytes(tlsSniChallenge.Value));

            for (var i = 1; i < z.Length; i++)
            {
                z[i] = sha256.ComputeHash(z[i - 1]);
            }

            // generate certs and install iis bindings
            var cleanupQueue = new List <Action>();

            var checkQueue = new List <Func <bool> >();

            foreach (var hex in z.Select(b =>
                                         BitConverter.ToString(b).Replace("-", "").ToLower()))
            {
                var sni = $"{hex.Substring(0, 32)}.{hex.Substring(32)}.acme.invalid";

                log.Information($"Preparing binding at: https://{domain}, sni: {sni}");

                var x509 = CertificateManager.GenerateSelfSignedCertificate(sni);

                CertificateManager.StoreCertificate(x509);

                var certStoreName = CertificateManager.GetStore().Name;

                // iisManager.InstallCertificateforBinding(certStoreName, x509.GetCertHash(),
                // managedCertificate.ServerSiteId, sni);

                // add check to the queue
                checkQueue.Add(() => _netUtil.CheckSNI(domain, sni).Result);

                // add cleanup actions to queue
                cleanupQueue.Add(() => iisManager.RemoveHttpsBinding(managedCertificate.ServerSiteId, sni));

                cleanupQueue.Add(() => CertificateManager.RemoveCertificate(x509));
            }

            // configure cleanup to execute the cleanup queue
            pendingAuth.Cleanup = () => cleanupQueue.ForEach(a => a());

            // perform our own config checks
            return(() => checkQueue.All(check => check()));
        }
Beispiel #2
0
        /// <summary>
        /// Prepares IIS to respond to a tls-sni-01 challenge
        /// </summary>
        /// <returns>
        /// A Boolean-returning Func. Invoke the Func to test the challenge response locally.
        /// </returns>
        private Func <bool> PrepareChallengeResponse_TlsSni01(IISManager iisManager, string domain, ManagedSite managedSite, PendingAuthorization pendingAuth)
        {
            var requestConfig   = managedSite.RequestConfig;
            var tlsSniChallenge = (ACMESharp.ACME.TlsSniChallenge)pendingAuth.Challenge.ChallengeData;
            var tlsSniAnswer    = (ACMESharp.ACME.TlsSniChallengeAnswer)tlsSniChallenge.Answer;
            var sha256          = System.Security.Cryptography.SHA256.Create();
            var z = new byte[tlsSniChallenge.IterationCount][];

            // compute n sha256 hashes, where n=challengedata.iterationcount
            z[0] = sha256.ComputeHash(Encoding.UTF8.GetBytes(tlsSniAnswer.KeyAuthorization));
            for (int i = 1; i < z.Length; i++)
            {
                z[i] = sha256.ComputeHash(z[i - 1]);
            }
            // generate certs and install iis bindings
            var cleanupQueue = new List <Action>();
            var checkQueue   = new List <Func <bool> >();

            foreach (string hex in z.Select(b =>
                                            BitConverter.ToString(b).Replace("-", "").ToLower()))
            {
                string sni = $"{hex.Substring(0, 32)}.{hex.Substring(32)}.acme.invalid";
                this.LogAction($"Preparing binding at: https://{domain}, sni: {sni}");

                var x509 = CertificateManager.GenerateTlsSni01Certificate(sni);
                CertificateManager.StoreCertificate(x509);
                iisManager.InstallCertificateforBinding(managedSite, x509, sni);

                // add check to the queue
                checkQueue.Add(() => NetUtil.CheckSNI(domain, sni));

                // add cleanup actions to queue
                cleanupQueue.Add(() => iisManager.RemoveHttpsBinding(managedSite, sni));
                cleanupQueue.Add(() => CertificateManager.RemoveCertificate(x509));
            }

            // configure cleanup to execute the cleanup queue
            pendingAuth.Cleanup = () => cleanupQueue.ForEach(a => a());

            // perform our own config checks
            pendingAuth.TlsSniConfigCheckedOK = true;
            return(() => checkQueue.All(check => check()));
        }