public void Initialize()
        {
            Log.Information("Initializing ACME client");

            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

            if (!File.Exists(_options.WellKnownFilePaths[WellKnownFile.AcmeSigner]))
            {
                throw new FileNotFoundException($"Signer file '{_options.WellKnownFilePaths[WellKnownFile.AcmeSigner]}' not found");
            }
            if (!File.Exists(_options.WellKnownFilePaths[WellKnownFile.AcmeRegistration]))
            {
                throw new FileNotFoundException($"Registration file '{_options.WellKnownFilePaths[WellKnownFile.AcmeRegistration]}' not found");
            }

            _signer.Init();

            using (FileStream signerStream = File.OpenRead(_options.WellKnownFilePaths[WellKnownFile.AcmeSigner]))
                _signer.Load(signerStream);

            _client.Signer  = _signer;
            _client.RootUrl = new Uri(_options.BaseUri);

            _client.Init();
            _client.GetDirectory(true);

            using (FileStream registrationStream = File.OpenRead(_options.WellKnownFilePaths[WellKnownFile.AcmeRegistration]))
                _client.Registration = AcmeRegistration.Load(registrationStream);

            _isInitialized = true;
        }
 /// <summary>
 /// Load a certificate signer from a file
 /// </summary>
 /// <param name="signer"></param>
 /// <param name="signerPath"></param>
 protected void LoadSignerFromFile(RS256Signer signer, string signerPath)
 {
     this.Logger.LogInfo(true, $"Loading Signer from {signerPath}");
     using (var signerStream = File.OpenRead(signerPath))
     {
         signer.Load(signerStream);
     }
 }
Exemplo n.º 3
0
        public static RS256Signer LoadFromFile(string signerPath)
        {
            var signer = new RS256Signer();

            signer.Init();

            using (var signerStream = File.OpenRead(signerPath))
                signer.Load(signerStream);

            return(signer);
        }
Exemplo n.º 4
0
        public void Test0190_RefreshCertificateRequest()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream(_testRegister_AcmeSignerFile, FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream(_testRegister_AcmeRegFile, FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                //var csrRaw = File.ReadAllBytes($"{_baseLocalStore}\\test-csr.der");
                //var csrB64u = JwsHelper.Base64UrlEncode(csrRaw);

                using (var client = BuildClient(testTagHeader: nameof(Test0190_RefreshCertificateRequest)))
                {
                    client.RootUrl      = _rootUrl;
                    client.Signer       = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    CertificateRequest certRequ;
                    using (var fs = new FileStream(_testCertRequ_AcmeCertRequFile, FileMode.Open))
                    {
                        certRequ = CertificateRequest.Load(fs);
                    }

                    client.RefreshCertificateRequest(certRequ, true);

                    _testCertRequRefreshed_AcmeCertRequFile = $"{_baseLocalStore}\\TestCertRequ-Refreshed.acmeCertRequ";
                    using (var fs = new FileStream(_testCertRequRefreshed_AcmeCertRequFile, FileMode.Create))
                    {
                        certRequ.Save(fs);
                    }

                    if (!string.IsNullOrEmpty(certRequ.CertificateContent))
                    {
                        _testCertRequRefreshed_CerFile = $"{_baseLocalStore}\\TestCertRequ-Refreshed.cer";
                        using (var fs = new FileStream(_testCertRequRefreshed_CerFile, FileMode.Create))
                        {
                            certRequ.SaveCertificate(fs);
                        }
                    }
                }
            }
        }
Exemplo n.º 5
0
        public void Test0141_HandleHttpChallenge()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream(_testRegister_AcmeSignerFile, FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream(_testRegister_AcmeRegFile, FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient(testTagHeader: nameof(Test0141_HandleHttpChallenge)))
                {
                    client.RootUrl      = _rootUrl;
                    client.Signer       = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    AuthorizationState authzState;
                    using (var fs = new FileStream(_testAuthz_AcmeAuthzFile, FileMode.Open))
                    {
                        authzState = AuthorizationState.Load(fs);
                    }

                    var authzChallenge = client.GenerateAuthorizeChallengeAnswer(authzState, AcmeProtocol.CHALLENGE_TYPE_HTTP);
                    _testAuthzChallengeHttpHandled_AcmeAuthzFile = $"{_baseLocalStore}\\TestAuthz-ChallengeAnswersHandleHttp.acmeAuthz";
                    using (var fs = new FileStream(_testAuthzChallengeHttpHandled_AcmeAuthzFile, FileMode.Create))
                    {
                        authzState.Save(fs);
                    }

                    var wsFilePath = authzChallenge.ChallengeAnswer.Key;
                    var wsFileBody = authzChallenge.ChallengeAnswer.Value;

                    var wsInfo = WebServerInfo.Load(File.ReadAllText("config\\webServerInfo.json"));
                    using (var s = new MemoryStream(Encoding.UTF8.GetBytes(wsFileBody)))
                    {
                        var fileUrl = new Uri($"http://{authzState.Identifier}/{wsFilePath}");
                        wsInfo.Provider.UploadFile(fileUrl, s);
                    }
                }
            }

            Thread.Sleep(90 * 1000);
        }
        public void Test0190_RefreshCertificateRequest()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeSigner", FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeReg", FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                //var csrRaw = File.ReadAllBytes($"{BASE_LOCAL_STORE}test-csr.der");
                //var csrB64u = JwsHelper.Base64UrlEncode(csrRaw);

                using (var client = BuildClient())
                {
                    client.RootUrl      = _rootUrl;
                    client.Signer       = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    CertificateRequest certRequ;
                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestCertRequ.acmeCertRequ", FileMode.Open))
                    {
                        certRequ = CertificateRequest.Load(fs);
                    }

                    client.RefreshCertificateRequest(certRequ, true);

                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestCertRequ-Refreshed.acmeCertRequ", FileMode.Create))
                    {
                        certRequ.Save(fs);
                    }

                    if (!string.IsNullOrEmpty(certRequ.CertificateContent))
                    {
                        using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestCertRequ-Refreshed.cer", FileMode.Create))
                        {
                            certRequ.SaveCertificate(fs);
                        }
                    }
                }
            }
        }
        public void Test0140_HandleHttpChallenge()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeSigner", FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeReg", FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient())
                {
                    client.RootUrl      = _rootUrl;
                    client.Signer       = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    AuthorizationState authzState;
                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz.acmeAuthz", FileMode.Open))
                    {
                        authzState = AuthorizationState.Load(fs);
                    }

                    var authzChallenge = client.GenerateAuthorizeChallengeAnswer(authzState, "simpleHttp");
                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz-ChallengeAnswersHandleHttp.acmeAuthz", FileMode.Create))
                    {
                        authzState.Save(fs);
                    }

                    var wsFilePath = authzChallenge.ChallengeAnswer.Key;
                    var wsFileBody = authzChallenge.ChallengeAnswer.Value;

                    var wsInfo = WebServerInfo.Load(File.ReadAllText("webServerInfo.json"));
                    using (var s = new MemoryStream(Encoding.UTF8.GetBytes(wsFileBody)))
                    {
                        var fileUrl = new Uri($"http://{authzState.Identifier}/{wsFilePath}");
                        wsInfo.Provider.UploadFile(fileUrl, s);
                    }
                }
            }

            Thread.Sleep(90 * 1000);
        }
Exemplo n.º 8
0
        public void Test0090_AuthorizeIdentifier()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream(_testRegister_AcmeSignerFile, FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream(_testRegister_AcmeRegFile, FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient(testTagHeader: nameof(Test0090_AuthorizeIdentifier)))
                {
                    client.RootUrl      = _rootUrl;
                    client.Signer       = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    var authzState = client.AuthorizeIdentifier(TEST_CN1);

                    foreach (var c in authzState.Challenges)
                    {
                        if (c.Type == AcmeProtocol.CHALLENGE_TYPE_DNS)
                        {
                            var dnsResponse = c.GenerateDnsChallengeAnswer(
                                authzState.Identifier, signer);
                        }
                        else if (c.Type == AcmeProtocol.CHALLENGE_TYPE_HTTP)
                        {
                            var httpResponse = c.GenerateHttpChallengeAnswer(
                                authzState.Identifier, signer);
                        }
                    }

                    _testAuthz_AcmeAuthzFile = $"{_baseLocalStore}\\TestAuthz.acmeAuthz";
                    using (var fs = new FileStream(_testAuthz_AcmeAuthzFile, FileMode.Create))
                    {
                        authzState.Save(fs);
                    }
                }
            }
        }
        public void Test0130_HandleDnsChallenge()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeSigner", FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeReg", FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient())
                {
                    client.RootUrl      = _rootUrl;
                    client.Signer       = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    AuthorizationState authzState;
                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz.acmeAuthz", FileMode.Open))
                    {
                        authzState = AuthorizationState.Load(fs);
                    }

                    var authzChallenge = client.GenerateAuthorizeChallengeAnswer(authzState, "dns");
                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz-ChallengeAnswersHandleDns.acmeAuthz", FileMode.Create))
                    {
                        authzState.Save(fs);
                    }

                    var dnsName   = authzChallenge.ChallengeAnswer.Key;
                    var dnsValue  = Regex.Replace(authzChallenge.ChallengeAnswer.Value, "\\s", "");
                    var dnsValues = Regex.Replace(dnsValue, "(.{100,100})", "$1\n").Split('\n');

                    var dnsInfo = DnsInfo.Load(File.ReadAllText("dnsInfo.json"));
                    dnsInfo.Provider.EditTxtRecord(dnsName, dnsValues);
                }
            }

            Thread.Sleep(90 * 1000);
        }
Exemplo n.º 10
0
        public void Test0120_GenerateChallengeAnswers()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream(_testRegister_AcmeSignerFile, FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream(_testRegister_AcmeRegFile, FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient(testTagHeader: nameof(Test0120_GenerateChallengeAnswers)))
                {
                    client.RootUrl      = _rootUrl;
                    client.Signer       = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    AuthorizationState authzState;
                    using (var fs = new FileStream(_testAuthz_AcmeAuthzFile, FileMode.Open))
                    {
                        authzState = AuthorizationState.Load(fs);
                    }

                    //client.GenerateAuthorizeChallengeAnswer(authzState, AcmeProtocol.CHALLENGE_TYPE_DNS);
                    //client.GenerateAuthorizeChallengeAnswer(authzState, AcmeProtocol.CHALLENGE_TYPE_LEGACY_HTTP);
                    client.GenerateAuthorizeChallengeAnswer(authzState, AcmeProtocol.CHALLENGE_TYPE_HTTP);

                    _testAuthzChallengeAnswers_AcmeAuthzFile = $"{_baseLocalStore}\\TestAuthz-ChallengeAnswers.acmeAuthz";
                    using (var fs = new FileStream(_testAuthzChallengeAnswers_AcmeAuthzFile, FileMode.Create))
                    {
                        authzState.Save(fs);
                    }
                }
            }
        }
        public void Test0090_AuthorizeIdentifier()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeSigner", FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeReg", FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient())
                {
                    client.RootUrl      = _rootUrl;
                    client.Signer       = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    var authzState = client.AuthorizeIdentifier(TEST_CN1);

                    foreach (var c in authzState.Challenges)
                    {
                        if (c.Type == "dns")
                        {
                            var dnsResponse = c.GenerateDnsChallengeAnswer(
                                authzState.Identifier, signer);
                        }
                    }

                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz.acmeAuthz", FileMode.Create))
                    {
                        authzState.Save(fs);
                    }
                }
            }
        }
Exemplo n.º 12
0
        public void Test0095_RefreshIdentifierAuthorization()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream(_testRegister_AcmeSignerFile, FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream(_testRegister_AcmeRegFile, FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient(testTagHeader: nameof(Test0095_RefreshIdentifierAuthorization)))
                {
                    client.RootUrl      = _rootUrl;
                    client.Signer       = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    AuthorizationState authzState;
                    using (var fs = new FileStream(_testAuthz_AcmeAuthzFile, FileMode.Open))
                    {
                        authzState = AuthorizationState.Load(fs);
                    }

                    var authzRefreshState = client.RefreshIdentifierAuthorization(authzState, true);

                    _testAuthzRefresh_AcmeAuthzFile = $"{_baseLocalStore}\\TestAuthz-Refresh.acmeAuthz";
                    using (var fs = new FileStream(_testAuthzRefresh_AcmeAuthzFile, FileMode.Create))
                    {
                        authzRefreshState.Save(fs);
                    }
                }
            }
        }
        public void Test0145_SubmitHttpChallengeAnswers()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeSigner", FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeReg", FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient())
                {
                    client.RootUrl      = _rootUrl;
                    client.Signer       = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    AuthorizationState authzState;
                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz-ChallengeAnswersHandleHttp.acmeAuthz", FileMode.Open))
                    {
                        authzState = AuthorizationState.Load(fs);
                    }

                    client.GenerateAuthorizeChallengeAnswer(authzState, "simpleHttp");
                    client.SubmitAuthorizeChallengeAnswer(authzState, "simpleHttp", true);

                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz-HttpChallengeAnswered.acmeAuthz", FileMode.Create))
                    {
                        authzState.Save(fs);
                    }
                }
            }
        }
Exemplo n.º 14
0
        public void Test0080_AuthorizeDnsBlacklisted()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream(_testRegister_AcmeSignerFile, FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream(_testRegister_AcmeRegFile, FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient(testTagHeader: nameof(Test0080_AuthorizeDnsBlacklisted)))
                {
                    client.RootUrl      = _rootUrl;
                    client.Signer       = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    try
                    {
                        client.AuthorizeIdentifier("acme-win-test.example.com");
                    }
                    catch (AcmeClient.AcmeWebException ex)
                    {
                        Assert.IsNotNull(ex.WebException);
                        Assert.IsNotNull(ex.Response);
                        Assert.IsNotNull(ex.Response.ProblemDetail);
                        Assert.AreEqual(HttpStatusCode.Forbidden, ex.Response.StatusCode);
                        Assert.AreEqual("urn:acme:error:unauthorized", ex.Response.ProblemDetail.Type);
                        StringAssert.Contains(ex.Response.ProblemDetail.Detail, "blacklist");
                    }
                }
            }
        }
        public void Test0095_RefreshIdentifierAuthorization()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeSigner", FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeReg", FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient())
                {
                    client.RootUrl      = _rootUrl;
                    client.Signer       = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    AuthorizationState authzState;
                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz.acmeAuthz", FileMode.Open))
                    {
                        authzState = AuthorizationState.Load(fs);
                    }

                    var authzRefreshState = client.RefreshIdentifierAuthorization(authzState, true);

                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz-Refresh.acmeAuthz", FileMode.Create))
                    {
                        authzRefreshState.Save(fs);
                    }
                }
            }
        }
        public void Test0100_RefreshAuthzDnsChallenge()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeSigner", FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeReg", FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient())
                {
                    client.RootUrl      = _rootUrl;
                    client.Signer       = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    AuthorizationState authzState;
                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz.acmeAuthz", FileMode.Open))
                    {
                        authzState = AuthorizationState.Load(fs);
                    }

                    client.RefreshAuthorizeChallenge(authzState, "dns", true);

                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz-DnsChallengeRefreshed.acmeAuthz", FileMode.Create))
                    {
                        authzState.Save(fs);
                    }
                }
            }
        }
Exemplo n.º 17
0
        public void Test0030_Register()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                if (!_wpConfig.UseNewSigner)
                {
                    // Re-use existing Signer config from stable local store
                    using (var fs = new FileStream(_testRegister_AcmeSignerFile, FileMode.Open))
                    {
                        signer.Load(fs);
                    }
                }
                _testRegister_AcmeSignerFile = $"{_baseLocalStore}\\TestRegister.acmeSigner";
                using (var fs = new FileStream(_testRegister_AcmeSignerFile, FileMode.Create))
                {
                    signer.Save(fs);
                }

                using (var client = BuildClient(testTagHeader: nameof(Test0030_Register)))
                {
                    client.RootUrl = _rootUrl;
                    client.Signer  = signer;
                    client.Init();

                    client.GetDirectory(true);

                    client.Register(new string[] { TEST_EM1, TEST_PH1, });

                    Assert.IsNotNull(client.Registration);
                    Assert.IsFalse(string.IsNullOrWhiteSpace(client.Registration.RegistrationUri));

                    _testRegister_AcmeRegFile = $"{_baseLocalStore}\\TestRegister.acmeReg";
                    using (var fs = new FileStream(_testRegister_AcmeRegFile, FileMode.Create))
                    {
                        client.Registration.Save(fs);
                    }
                }
            }
        }
Exemplo n.º 18
0
        public void Test0160_RequestCertificateInvalidCsr()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream(_testRegister_AcmeSignerFile, FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream(_testRegister_AcmeRegFile, FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient(testTagHeader: nameof(Test0160_RequestCertificateInvalidCsr)))
                {
                    client.RootUrl      = _rootUrl;
                    client.Signer       = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    try
                    {
                        client.RequestCertificate("FOOBARNON");
                        Assert.Fail("WebException expected");
                    }
                    catch (AcmeClient.AcmeWebException ex)
                    {
                        Assert.IsNotNull(ex.WebException);
                        Assert.IsNotNull(ex.Response);
                        Assert.AreEqual(HttpStatusCode.BadRequest, ex.Response.StatusCode);
                    }
                }
            }
        }
Exemplo n.º 19
0
        public void Test0040_RegisterEmptyUpdate()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream(_testRegister_AcmeSignerFile, FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream(_testRegister_AcmeRegFile, FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient(testTagHeader: nameof(Test0040_RegisterEmptyUpdate)))
                {
                    client.RootUrl      = _rootUrl;
                    client.Signer       = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    // Do a simple update with no data changes requested
                    client.UpdateRegistration(true);

                    Assert.IsNotNull(client.Registration);
                    Assert.IsFalse(string.IsNullOrWhiteSpace(client.Registration.RegistrationUri));

                    _testRegisterUpdate_AcmeRegFile = $"{_baseLocalStore}\\TestRegisterEmptyUpdate.acmeReg";
                    using (var fs = new FileStream(_testRegisterUpdate_AcmeRegFile, FileMode.Create))
                    {
                        client.Registration.Save(fs);
                    }
                }
            }
        }
Exemplo n.º 20
0
        public void Test0060_RegisterUpdateContacts()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream(_testRegister_AcmeSignerFile, FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream(_testRegister_AcmeRegFile, FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient(testTagHeader: nameof(Test0060_RegisterUpdateContacts)))
                {
                    client.RootUrl      = _rootUrl;
                    client.Signer       = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    client.UpdateRegistration(true, contacts: new string[] { TEST_EM2, });

                    Assert.IsNotNull(client.Registration);
                    Assert.IsFalse(string.IsNullOrWhiteSpace(client.Registration.RegistrationUri));

                    _testRegisterUpdate_AcmeRegFile = $"{_baseLocalStore}\\TestRegisterUpdate.acmeReg";
                    using (var fs = new FileStream(_testRegisterUpdate_AcmeRegFile, FileMode.Create))
                    {
                        client.Registration.Save(fs);
                    }
                }
            }
        }
        public void Test0040_RegisterEmptyUpdate()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeSigner", FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeReg", FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient())
                {
                    client.RootUrl      = _rootUrl;
                    client.Signer       = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    // Do a simple update with no data changes requested
                    client.UpdateRegistration(true);

                    Assert.IsNotNull(client.Registration);
                    Assert.IsFalse(string.IsNullOrWhiteSpace(client.Registration.RegistrationUri));

                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegisterUpdate.acmeReg", FileMode.Create))
                    {
                        client.Registration.Save(fs);
                    }
                }
            }
        }
        public void Init()
        {
            _RegistrationJsonPath = Path.Combine(Config.Path, "Registration.json");
            _SignerXmlPath        = Path.Combine(Config.Path, "Signer.xml");

            _Signer = new RS256Signer();
            _Signer.Init();

            // Load signer from file if it exists
            if (File.Exists(_SignerXmlPath))
            {
                Globals.Log($"Loading {_SignerXmlPath}");
                using (var FS = File.OpenRead(_SignerXmlPath)) _Signer.Load(FS);
            }

            // Init client
            _Client = new AcmeClient(new Uri(Config.BaseUri), new AcmeServerDirectory(), _Signer);
            _Client.Init();
            _Client.GetDirectory(true);

            // Load registration from file, or prompt for email and create registration
            LoadOrCreateRegistration();
        }
        public void Test0060_RegisterUpdateContacts()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeSigner", FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeReg", FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient())
                {
                    client.RootUrl      = _rootUrl;
                    client.Signer       = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    client.UpdateRegistration(true, contacts: new string[] { TEST_EM2, });

                    Assert.IsNotNull(client.Registration);
                    Assert.IsFalse(string.IsNullOrWhiteSpace(client.Registration.RegistrationUri));

                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegisterUpdate.acmeReg", FileMode.Create))
                    {
                        client.Registration.Save(fs);
                    }
                }
            }
        }
Exemplo n.º 24
0
        public void Test0070_RegisterDuplicate()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream(_testRegister_AcmeSignerFile, FileMode.Open))
                {
                    signer.Load(fs);
                }

                using (var client = BuildClient(testTagHeader: nameof(Test0070_RegisterDuplicate)))
                {
                    client.RootUrl = _rootUrl;
                    client.Signer  = signer;
                    client.Init();

                    client.GetDirectory(true);

                    try
                    {
                        client.Register(new string[]
                        {
                            "mailto:[email protected]",
                            "tel:+14105551212",
                        });
                        Assert.Fail("WebException expected");
                    }
                    catch (AcmeClient.AcmeWebException ex)
                    {
                        Assert.IsNotNull(ex.WebException);
                        Assert.IsNotNull(ex.Response);
                        Assert.AreEqual(HttpStatusCode.Conflict, ex.Response.StatusCode);
                    }
                }
            }
        }
Exemplo n.º 25
0
        public AcmeClient Register(RS256Signer signer)
        {
            if (!Directory.Exists(configPath))
            {
                Directory.CreateDirectory(configPath);
            }
            var email = config.RegistrationEmail;

            try
            {
                signer.Init();

                var signerPath = Path.Combine(configPath, "Signer");
                if (File.Exists(signerPath))
                {
                    Trace.TraceInformation($"Loading Signer from {signerPath}");
                    using (var signerStream = File.OpenRead(signerPath))
                        signer.Load(signerStream);
                }

                var client = new AcmeClient(new Uri(this.baseURI), new AcmeServerDirectory(), signer);

                client.Init();
                Trace.TraceInformation("\nGetting AcmeServerDirectory");
                client.GetDirectory(true);

                var registrationPath = Path.Combine(configPath, "Registration");
                if (File.Exists(registrationPath))
                {
                    Trace.TraceInformation($"Loading Registration from {registrationPath}");
                    using (var registrationStream = File.OpenRead(registrationPath))
                        client.Registration = AcmeRegistration.Load(registrationStream);
                }
                else
                {
                    var contacts = new string[] { };
                    if (!String.IsNullOrEmpty(email))
                    {
                        email    = "mailto:" + email;
                        contacts = new string[] { email };
                    }

                    Trace.TraceInformation("Calling Register");
                    var registration = client.Register(contacts);


                    Trace.TraceInformation("Updating Registration");
                    client.UpdateRegistration(true, true);

                    Trace.TraceInformation("Saving Registration");
                    using (var registrationStream = File.OpenWrite(registrationPath))
                        client.Registration.Save(registrationStream);

                    Trace.TraceInformation("Saving Signer");
                    using (var signerStream = File.OpenWrite(signerPath))
                        signer.Save(signerStream);
                }
                return(client);
            }
            catch (Exception e)
            {
                var acmeWebException = e as AcmeClient.AcmeWebException;
                if (acmeWebException != null)
                {
                    Trace.TraceError(acmeWebException.Message);
                    Trace.TraceError("ACME Server Returned:");
                    Trace.TraceError(acmeWebException.Response.ContentAsString);
                }
                else
                {
                    Trace.TraceError(e.ToString());
                }
                throw;
            }
        }
Exemplo n.º 26
0
        public static string RequestAndInstallInternal(Target target)
        {
            BaseURI    = target.BaseUri ?? "https://acme-staging.api.letsencrypt.org/";
            configPath = ConfigPath(BaseURI);
            try
            {
                webSiteClient = ArmHelper.GetWebSiteManagementClient(target);
            }
            catch (Exception ex)
            {
                Trace.TraceError("Unabled to create Azure Web Site Management client " + ex.ToString());
                throw;
            }

            if (!Directory.Exists(configPath))
            {
                Directory.CreateDirectory(configPath);
            }
            var email = target.Email;

            try
            {
                using (var signer = new RS256Signer())
                {
                    signer.Init();

                    var signerPath = Path.Combine(configPath, "Signer");
                    if (File.Exists(signerPath))
                    {
                        Trace.TraceInformation($"Loading Signer from {signerPath}");
                        using (var signerStream = File.OpenRead(signerPath))
                            signer.Load(signerStream);
                    }

                    using (client = new AcmeClient(new Uri(BaseURI), new AcmeServerDirectory(), signer))
                    {
                        client.Init();
                        Trace.TraceInformation("\nGetting AcmeServerDirectory");
                        client.GetDirectory(true);

                        var registrationPath = Path.Combine(configPath, "Registration");
                        if (File.Exists(registrationPath))
                        {
                            Trace.TraceInformation($"Loading Registration from {registrationPath}");
                            using (var registrationStream = File.OpenRead(registrationPath))
                                client.Registration = AcmeRegistration.Load(registrationStream);
                        }
                        else
                        {
                            var contacts = new string[] { };
                            if (!String.IsNullOrEmpty(email))
                            {
                                email    = "mailto:" + email;
                                contacts = new string[] { email };
                            }

                            Trace.TraceInformation("Calling Register");
                            var registration = client.Register(contacts);


                            Trace.TraceInformation("Updating Registration");
                            client.UpdateRegistration(true, true);

                            Trace.TraceInformation("Saving Registration");
                            using (var registrationStream = File.OpenWrite(registrationPath))
                                client.Registration.Save(registrationStream);

                            Trace.TraceInformation("Saving Signer");
                            using (var signerStream = File.OpenWrite(signerPath))
                                signer.Save(signerStream);
                        }

                        //                        if (Options.Renew)
                        //                        {
                        //                            CheckRenewals();
                        //#if DEBUG
                        //                            Trace.TraceInformation("Press enter to continue.");
                        //                            Trace.ReadLine();
                        //#endif
                        //                            return;
                        //                        }
                        return(Auto(target));
                    }
                }
            }
            catch (Exception e)
            {
                var acmeWebException = e as AcmeClient.AcmeWebException;
                if (acmeWebException != null)
                {
                    Trace.TraceError(acmeWebException.Message);
                    Trace.TraceError("ACME Server Returned:");
                    Trace.TraceError(acmeWebException.Response.ContentAsString);
                }
                else
                {
                    Trace.TraceError(e.ToString());
                }
                throw;
            }
        }
Exemplo n.º 27
0
        static void Main(string[] args)
        {
            var commandLineParseResult = Parser.Default.ParseArguments<Options>(args);
            var parsed = commandLineParseResult as Parsed<Options>;
            if (parsed == null)
            {
#if DEBUG
                Console.WriteLine("Press enter to continue.");
                Console.ReadLine();
#endif
                return; // not parsed
            }
            options = parsed.Value;

            Console.WriteLine("Let's Encrypt (Simple Windows ACME Client)");

            BaseURI = options.BaseURI;
            if (options.Test)
                BaseURI = "https://acme-staging.api.letsencrypt.org/";

            //Console.Write("\nUse production Let's Encrypt server? (Y/N) ");
            //if (PromptYesNo())
            //    BaseURI = ProductionBaseURI;

            Console.WriteLine($"\nACME Server: {BaseURI}");

            settings = new Settings(clientName, BaseURI);

            configPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), clientName, CleanFileName(BaseURI));
            Console.WriteLine("Config Folder: " + configPath);
            Directory.CreateDirectory(configPath);

            using (var signer = new RS256Signer())
            {
                signer.Init();

                var signerPath = Path.Combine(configPath, "Signer");
                if (File.Exists(signerPath))
                {
                    Console.WriteLine($"Loading Signer from {signerPath}");
                    using (var signerStream = File.OpenRead(signerPath))
                        signer.Load(signerStream);
                }

                using (client = new AcmeClient(new Uri(BaseURI), new AcmeServerDirectory(), signer))
                {
                    client.Init();
                    Console.WriteLine("\nGetting AcmeServerDirectory");
                    client.GetDirectory(true);

                    var registrationPath = Path.Combine(configPath, "Registration");
                    if (File.Exists(registrationPath))
                    {
                        Console.WriteLine($"Loading Registration from {registrationPath}");
                        using (var registrationStream = File.OpenRead(registrationPath))
                            client.Registration = AcmeRegistration.Load(registrationStream);
                    }
                    else
                    {
                        Console.WriteLine("Calling Register");
                        var registration = client.Register(new string[] { });

                        if (!options.AcceptTOS && !options.Renew)
                        {
                            Console.WriteLine($"Do you agree to {registration.TosLinkUri}? (Y/N) ");
                            if (!PromptYesNo())
                                return;
                        }

                        Console.WriteLine("Updating Registration");
                        client.UpdateRegistration(true, true);

                        Console.WriteLine("Saving Registration");
                        using (var registrationStream = File.OpenWrite(registrationPath))
                            client.Registration.Save(registrationStream);

                        Console.WriteLine("Saving Signer");
                        using (var signerStream = File.OpenWrite(signerPath))
                            signer.Save(signerStream);
                    }

                    if (options.Renew)
                    {
                        CheckRenewals();
#if DEBUG
                        Console.WriteLine("Press enter to continue.");
                        Console.ReadLine();
#endif
                        return;
                    }

                    Console.WriteLine("\nScanning IIS 7 Site Bindings for Hosts (Elevated Permissions Required)");
                    if (!IsElevated)
                    {
                        Console.WriteLine("Elevated Permissions Required. Please run under an administrator console.");
#if DEBUG
                        Console.WriteLine("Press enter to continue.");
                        Console.ReadLine();
#endif
                        return;
                    }


                    var bindings = GetHostNames();
                    if (bindings.Count == 0)
                    {
                        Console.WriteLine("No IIS bindings with host names were found. Please add one using IIS Manager. A host name and site path are required to verify domain ownership.");
                        return;
                    }

                    Console.WriteLine("IIS Bindings");
                    var count = 1;
                    foreach (var binding in bindings)
                    {
                        Console.WriteLine($" {count}: {binding}");
                        count++;
                    }

                    Console.WriteLine();
                    Console.WriteLine(" A: Get Certificates for All Bindings");
                    Console.WriteLine(" Q: Quit");
                    Console.Write("Which binding do you want to get a cert for: ");
                    var response = Console.ReadLine();
                    switch (response.ToLowerInvariant())
                    {
                        case "a":
                            foreach (var binding in bindings)
                            {
                                Auto(binding);
                            }
                            break;
                        case "q":
                            return;
                        default:
                            var bindingId = 0;
                            if (Int32.TryParse(response, out bindingId))
                            {
                                bindingId--;
                                if (bindingId >= 0 && bindingId < bindings.Count)
                                {
                                    var binding = bindings[bindingId];
                                    Auto(binding);
                                }
                            }
                            break;
                    }
                }
            }

#if DEBUG
            Console.WriteLine("Press enter to continue.");
            Console.ReadLine();
#endif
        }
        public void Test0190_RefreshCertificateRequest()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream(_testRegister_AcmeSignerFile, FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream(_testRegister_AcmeRegFile, FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                //var csrRaw = File.ReadAllBytes($"{_baseLocalStore}\\test-csr.der");
                //var csrB64u = JwsHelper.Base64UrlEncode(csrRaw);

                using (var client = BuildClient(testTagHeader: nameof(Test0190_RefreshCertificateRequest)))
                {
                    client.RootUrl = _rootUrl;
                    client.Signer = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    CertificateRequest certRequ;
                    using (var fs = new FileStream(_testCertRequ_AcmeCertRequFile, FileMode.Open))
                    {
                        certRequ = CertificateRequest.Load(fs);
                    }

                    client.RefreshCertificateRequest(certRequ, true);

                    _testCertRequRefreshed_AcmeCertRequFile = $"{_baseLocalStore}\\TestCertRequ-Refreshed.acmeCertRequ";
                    using (var fs = new FileStream(_testCertRequRefreshed_AcmeCertRequFile, FileMode.Create))
                    {
                        certRequ.Save(fs);
                    }

                    if (!string.IsNullOrEmpty(certRequ.CertificateContent))
                    {
                        _testCertRequRefreshed_CerFile = $"{_baseLocalStore}\\TestCertRequ-Refreshed.cer";
                        using (var fs = new FileStream(_testCertRequRefreshed_CerFile, FileMode.Create))
                        {
                            certRequ.SaveCertificate(fs);
                        }
                    }
                }
            }
        }
        public void Test0040_RegisterEmptyUpdate()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream(_testRegister_AcmeSignerFile, FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream(_testRegister_AcmeRegFile, FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient(testTagHeader: nameof(Test0040_RegisterEmptyUpdate)))
                {
                    client.RootUrl = _rootUrl;
                    client.Signer = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    // Do a simple update with no data changes requested
                    client.UpdateRegistration(true);

                    Assert.IsNotNull(client.Registration);
                    Assert.IsFalse(string.IsNullOrWhiteSpace(client.Registration.RegistrationUri));

                    _testRegisterUpdate_AcmeRegFile = $"{_baseLocalStore}\\TestRegisterEmptyUpdate.acmeReg";
                    using (var fs = new FileStream(_testRegisterUpdate_AcmeRegFile, FileMode.Create))
                    {
                        client.Registration.Save(fs);
                    }
                }
            }
        }
        public void Test0090_AuthorizeIdentifier()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream(_testRegister_AcmeSignerFile, FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream(_testRegister_AcmeRegFile, FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient(testTagHeader: nameof(Test0090_AuthorizeIdentifier)))
                {
                    client.RootUrl = _rootUrl;
                    client.Signer = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    var authzState = client.AuthorizeIdentifier(TEST_CN1);

                    foreach (var c in authzState.Challenges)
                    {
                        if (c.Type == AcmeProtocol.CHALLENGE_TYPE_LEGACY_DNS
                                || c.Type == AcmeProtocol.CHALLENGE_TYPE_DNS)
                        {
                            var dnsResponse = c.GenerateDnsChallengeAnswer(
                                    authzState.Identifier, signer);
                        }
                        else if (c.Type == AcmeProtocol.CHALLENGE_TYPE_LEGACY_HTTP)
                        {
                            var httpResponse = c.GenerateLegacyHttpChallengeAnswer(
                                authzState.Identifier, signer, false);
                        }
                        else if (c.Type == AcmeProtocol.CHALLENGE_TYPE_HTTP)
                        {
                            var httpResponse = c.GenerateHttpChallengeAnswer(
                                authzState.Identifier, signer);
                        }
                    }

                    _testAuthz_AcmeAuthzFile = $"{_baseLocalStore}\\TestAuthz.acmeAuthz";
                    using (var fs = new FileStream(_testAuthz_AcmeAuthzFile, FileMode.Create))
                    {
                        authzState.Save(fs);
                    }
                }
            }
        }
        public void Test0095_RefreshIdentifierAuthorization()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeSigner", FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeReg", FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient())
                {
                    client.RootUrl = _rootUrl;
                    client.Signer = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    AuthorizationState authzState;
                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz.acmeAuthz", FileMode.Open))
                    {
                        authzState = AuthorizationState.Load(fs);
                    }

                    var authzRefreshState = client.RefreshIdentifierAuthorization(authzState, true);

                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz-Refresh.acmeAuthz", FileMode.Create))
                    {
                        authzRefreshState.Save(fs);
                    }
                }
            }
        }
        public void Test0100_RefreshAuthzDnsChallenge()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeSigner", FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeReg", FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient())
                {
                    client.RootUrl = _rootUrl;
                    client.Signer = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    AuthorizationState authzState;
                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz.acmeAuthz", FileMode.Open))
                    {
                        authzState = AuthorizationState.Load(fs);
                    }

                    client.RefreshAuthorizeChallenge(authzState, "dns", true);

                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz-DnsChallengeRefreshed.acmeAuthz", FileMode.Create))
                    {
                        authzState.Save(fs);
                    }
                }
            }
        }
        public void Test0130_HandleDnsChallenge()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeSigner", FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeReg", FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient())
                {
                    client.RootUrl = _rootUrl;
                    client.Signer = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    AuthorizationState authzState;
                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz.acmeAuthz", FileMode.Open))
                    {
                        authzState = AuthorizationState.Load(fs);
                    }

                    var authzChallenge = client.GenerateAuthorizeChallengeAnswer(authzState, "dns");
                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz-ChallengeAnswersHandleDns.acmeAuthz", FileMode.Create))
                    {
                        authzState.Save(fs);
                    }

                    var dnsName = authzChallenge.ChallengeAnswer.Key;
                    var dnsValue = Regex.Replace(authzChallenge.ChallengeAnswer.Value, "\\s", "");
                    var dnsValues = Regex.Replace(dnsValue, "(.{100,100})", "$1\n").Split('\n');

                    var dnsInfo = DnsInfo.Load(File.ReadAllText("dnsInfo.json"));
                    dnsInfo.Provider.EditTxtRecord(dnsName, dnsValues);
                }
            }

            Thread.Sleep(90 * 1000);
        }
Exemplo n.º 34
0
        static void Main(string[] args)
        {
            var commandLineParseResult = Parser.Default.ParseArguments<Options>(args);
            var parsed = commandLineParseResult as Parsed<Options>;
            if (parsed == null)
            {
#if DEBUG
                Console.WriteLine("Press enter to continue.");
                Console.ReadLine();
#endif
                return; // not parsed
            }
            Options = parsed.Value;

            Console.WriteLine("Let's Encrypt (Simple Windows ACME Client)");

            BaseURI = Options.BaseURI;
            if (Options.Test)
                BaseURI = "https://acme-staging.api.letsencrypt.org/";

            //Console.Write("\nUse production Let's Encrypt server? (Y/N) ");
            //if (PromptYesNo())
            //    BaseURI = ProductionBaseURI;

            Console.WriteLine($"\nACME Server: {BaseURI}");

            settings = new Settings(clientName, BaseURI);

            configPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), clientName, CleanFileName(BaseURI));
            Console.WriteLine("Config Folder: " + configPath);
            Directory.CreateDirectory(configPath);

            try
            {
                using (var signer = new RS256Signer())
                {
                    signer.Init();

                    var signerPath = Path.Combine(configPath, "Signer");
                    if (File.Exists(signerPath))
                    {
                        Console.WriteLine($"Loading Signer from {signerPath}");
                        using (var signerStream = File.OpenRead(signerPath))
                            signer.Load(signerStream);
                    }

                    using (client = new AcmeClient(new Uri(BaseURI), new AcmeServerDirectory(), signer))
                    {
                        client.Init();
                        Console.WriteLine("\nGetting AcmeServerDirectory");
                        client.GetDirectory(true);

                        var registrationPath = Path.Combine(configPath, "Registration");
                        if (File.Exists(registrationPath))
                        {
                            Console.WriteLine($"Loading Registration from {registrationPath}");
                            using (var registrationStream = File.OpenRead(registrationPath))
                                client.Registration = AcmeRegistration.Load(registrationStream);
                        }
                        else
                        {
                            Console.WriteLine("Calling Register");
                            var registration = client.Register(new string[] { });

                            if (!Options.AcceptTOS && !Options.Renew)
                            {
                                Console.WriteLine($"Do you agree to {registration.TosLinkUri}? (Y/N) ");
                                if (!PromptYesNo())
                                    return;
                            }

                            Console.WriteLine("Updating Registration");
                            client.UpdateRegistration(true, true);

                            Console.WriteLine("Saving Registration");
                            using (var registrationStream = File.OpenWrite(registrationPath))
                                client.Registration.Save(registrationStream);

                            Console.WriteLine("Saving Signer");
                            using (var signerStream = File.OpenWrite(signerPath))
                                signer.Save(signerStream);
                        }

                        if (Options.Renew)
                        {
                            CheckRenewals();
#if DEBUG
                            Console.WriteLine("Press enter to continue.");
                            Console.ReadLine();
#endif
                            return;
                        }

                        var targets = new List<Target>();
                        foreach (var plugin in Target.Plugins.Values)
                        {
                            targets.AddRange(plugin.GetTargets());
                        }

                        if (targets.Count == 0)
                        {
                            Console.WriteLine("No targets found.");
                        }
                        else
                        {
                            var count = 1;
                            foreach (var binding in targets)
                            {
                                Console.WriteLine($" {count}: {binding}");
                                count++;
                            }
                        }

                        Console.WriteLine();
                        foreach (var plugin in Target.Plugins.Values)
                        {
                            plugin.PrintMenu();
                        }

                        Console.WriteLine(" A: Get certificates for all hosts");
                        Console.WriteLine(" Q: Quit");
                        Console.Write("Which host do you want to get a certificate for: ");
                        var response = Console.ReadLine().ToLowerInvariant();
                        switch (response)
                        {
                            case "a":
                                foreach (var target in targets)
                                {
                                    Auto(target);
                                }
                                break;
                            case "q":
                                return;
                            default:
                                var targetId = 0;
                                if (Int32.TryParse(response, out targetId))
                                {
                                    targetId--;
                                    if (targetId >= 0 && targetId < targets.Count)
                                    {
                                        var binding = targets[targetId];
                                        Auto(binding);
                                    }
                                }
                                else
                                {
                                    foreach (var plugin in Target.Plugins.Values)
                                    {
                                        plugin.HandleMenuResponse(response, targets);
                                    }
                                }
                                break;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                var acmeWebException = e as AcmeClient.AcmeWebException;
                if (acmeWebException != null)
                {
                    Console.WriteLine(acmeWebException.Message);
                    Console.WriteLine("ACME Server Returned:");
                    Console.WriteLine(acmeWebException.Response.ContentAsString);
                }
                else
                {
                    Console.WriteLine(e);
                }
                Console.ResetColor();
            }

#if DEBUG
            Console.WriteLine("Press enter to continue.");
            Console.ReadLine();
#endif
        }
        public void Test0140_HandleHttpChallenge()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeSigner", FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeReg", FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient())
                {
                    client.RootUrl = _rootUrl;
                    client.Signer = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    AuthorizationState authzState;
                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz.acmeAuthz", FileMode.Open))
                    {
                        authzState = AuthorizationState.Load(fs);
                    }

                    var authzChallenge = client.GenerateAuthorizeChallengeAnswer(authzState, "simpleHttp");
                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz-ChallengeAnswersHandleHttp.acmeAuthz", FileMode.Create))
                    {
                        authzState.Save(fs);
                    }

                    var wsFilePath = authzChallenge.ChallengeAnswer.Key;
                    var wsFileBody = authzChallenge.ChallengeAnswer.Value;

                    var wsInfo = WebServerInfo.Load(File.ReadAllText("webServerInfo.json"));
                    using (var s = new MemoryStream(Encoding.UTF8.GetBytes(wsFileBody)))
                    {
                        var fileUrl = new Uri($"http://{authzState.Identifier}/{wsFilePath}");
                        wsInfo.Provider.UploadFile(fileUrl, s);
                    }
                }
            }

            Thread.Sleep(90 * 1000);
        }
        public void Test0190_RefreshCertificateRequest()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeSigner", FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeReg", FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                //var csrRaw = File.ReadAllBytes($"{BASE_LOCAL_STORE}test-csr.der");
                //var csrB64u = JwsHelper.Base64UrlEncode(csrRaw);

                using (var client = BuildClient())
                {
                    client.RootUrl = _rootUrl;
                    client.Signer = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    CertificateRequest certRequ;
                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestCertRequ.acmeCertRequ", FileMode.Open))
                    {
                        certRequ = CertificateRequest.Load(fs);
                    }

                    client.RefreshCertificateRequest(certRequ, true);

                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestCertRequ-Refreshed.acmeCertRequ", FileMode.Create))
                    {
                        certRequ.Save(fs);
                    }

                    if (!string.IsNullOrEmpty(certRequ.CertificateContent))
                    {
                        using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestCertRequ-Refreshed.cer", FileMode.Create))
                        {
                            certRequ.SaveCertificate(fs);
                        }
                    }
                }
            }
        }
        public void Test0170_GenCsrAndRequestCertificate()
        {
            var rsaKeys = CsrHelper.GenerateRsaPrivateKey();
            using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestGenCsr-rsaKeys.txt", FileMode.Create))
            {
                rsaKeys.Save(fs);
            }

            var csrDetails = new CsrHelper.CsrDetails
            {
                CommonName = TEST_CN1
            };
            var csr = CsrHelper.GenerateCsr(csrDetails, rsaKeys);
            using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestGenCsr-csrDetails.txt", FileMode.Create))
            {
                csrDetails.Save(fs);
            }
            using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestGenCsr-csr.txt", FileMode.Create))
            {
                csr.Save(fs);
            }

            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeSigner", FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeReg", FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                byte[] derRaw;
                using (var bs = new MemoryStream())
                {
                    csr.ExportAsDer(bs);
                    derRaw = bs.ToArray();
                }
                var derB64u = JwsHelper.Base64UrlEncode(derRaw);

                using (var client = BuildClient())
                {
                    client.RootUrl = _rootUrl;
                    client.Signer = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    var certRequ = client.RequestCertificate(derB64u);

                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestCertRequ.acmeCertRequ", FileMode.Create))
                    {
                        certRequ.Save(fs);
                    }
                }
            }
        }
        public void Test0160_RequestCertificateInvalidCsr()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeSigner", FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeReg", FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient())
                {
                    client.RootUrl = _rootUrl;
                    client.Signer = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    try
                    {
                        client.RequestCertificate("FOOBARNON");
                        Assert.Fail("WebException expected");
                    }
                    catch (AcmeClient.AcmeWebException ex)
                    {
                        Assert.IsNotNull(ex.WebException);
                        Assert.IsNotNull(ex.Response);
                        Assert.AreEqual(HttpStatusCode.BadRequest, ex.Response.StatusCode);
                    }
                }
            }
        }
        public void Test0110_RefreshAuthzLegacyHttpChallenge()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream(_testRegister_AcmeSignerFile, FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream(_testRegister_AcmeRegFile, FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient(testTagHeader: nameof(Test0110_RefreshAuthzLegacyHttpChallenge)))
                {
                    client.RootUrl = _rootUrl;
                    client.Signer = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    AuthorizationState authzState;
                    using (var fs = new FileStream(_testAuthz_AcmeAuthzFile, FileMode.Open))
                    {
                        authzState = AuthorizationState.Load(fs);
                    }

                    client.RefreshAuthorizeChallenge(authzState, AcmeProtocol.CHALLENGE_TYPE_LEGACY_HTTP, true);

                    _testAuthzChallengeLegacyHttpRefresh_AcmeAuthzFile = $"{_baseLocalStore}\\TestAuthz-LegacyHttpChallengeRefreshed.acmeAuthz";
                    using (var fs = new FileStream(_testAuthzChallengeLegacyHttpRefresh_AcmeAuthzFile, FileMode.Create))
                    {
                        authzState.Save(fs);
                    }
                }
            }
        }
        public void Test0090_AuthorizeIdentifier()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeSigner", FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeReg", FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient())
                {
                    client.RootUrl = _rootUrl;
                    client.Signer = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    var authzState = client.AuthorizeIdentifier(TEST_CN1);

                    foreach (var c in authzState.Challenges)
                    {
                        if (c.Type == "dns")
                        {
                            var dnsResponse = c.GenerateDnsChallengeAnswer(
                                    authzState.Identifier, signer);
                        }
                    }

                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz.acmeAuthz", FileMode.Create))
                    {
                        authzState.Save(fs);
                    }
                }
            }
        }
        public void Test0095_RefreshIdentifierAuthorization()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream(_testRegister_AcmeSignerFile, FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream(_testRegister_AcmeRegFile, FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient(testTagHeader: nameof(Test0095_RefreshIdentifierAuthorization)))
                {
                    client.RootUrl = _rootUrl;
                    client.Signer = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    AuthorizationState authzState;
                    using (var fs = new FileStream(_testAuthz_AcmeAuthzFile, FileMode.Open))
                    {
                        authzState = AuthorizationState.Load(fs);
                    }

                    var authzRefreshState = client.RefreshIdentifierAuthorization(authzState, true);

                    _testAuthzRefresh_AcmeAuthzFile = $"{_baseLocalStore}\\TestAuthz-Refresh.acmeAuthz";
                    using (var fs = new FileStream(_testAuthzRefresh_AcmeAuthzFile, FileMode.Create))
                    {
                        authzRefreshState.Save(fs);
                    }
                }
            }
        }
        public void Test0080_AuthorizeDnsBlacklisted()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeSigner", FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeReg", FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient())
                {
                    client.RootUrl = _rootUrl;
                    client.Signer = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    try
                    {
                        client.AuthorizeIdentifier("acme-win-test.example.com");
                    }
                    catch (AcmeClient.AcmeWebException ex)
                    {
                        Assert.IsNotNull(ex.WebException);
                        Assert.IsNotNull(ex.Response);
                        Assert.IsNotNull(ex.Response.ProblemDetail);
                        Assert.AreEqual(HttpStatusCode.Forbidden, ex.Response.StatusCode);
                        Assert.AreEqual("urn:acme:error:unauthorized", ex.Response.ProblemDetail.Type);
                        StringAssert.Contains(ex.Response.ProblemDetail.Detail, "blacklist");
                    }
                }
            }
        }
        public void Test0060_RegisterUpdateContacts()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream(_testRegister_AcmeSignerFile, FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream(_testRegister_AcmeRegFile, FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient(testTagHeader: nameof(Test0060_RegisterUpdateContacts)))
                {
                    client.RootUrl = _rootUrl;
                    client.Signer = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    client.UpdateRegistration(true, contacts: new string[] { TEST_EM2, });

                    Assert.IsNotNull(client.Registration);
                    Assert.IsFalse(string.IsNullOrWhiteSpace(client.Registration.RegistrationUri));

                    _testRegisterUpdate_AcmeRegFile = $"{_baseLocalStore}\\TestRegisterUpdate.acmeReg";
                    using (var fs = new FileStream(_testRegisterUpdate_AcmeRegFile, FileMode.Create))
                    {
                        client.Registration.Save(fs);
                    }
                }
            }
        }
        public void Test0070_RegisterDuplicate()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeSigner", FileMode.Open))
                {
                    signer.Load(fs);
                }

                using (var client = BuildClient())
                {
                    client.RootUrl = _rootUrl;
                    client.Signer = signer;
                    client.Init();

                    client.GetDirectory(true);

                    try
                    {
                        client.Register(new string[]
                                {
                                    "mailto:[email protected]",
                                    "tel:+14105551212",
                                });
                        Assert.Fail("WebException expected");
                    }
                    catch (AcmeClient.AcmeWebException ex)
                    {
                        Assert.IsNotNull(ex.WebException);
                        Assert.IsNotNull(ex.Response);
                        Assert.AreEqual(HttpStatusCode.Conflict, ex.Response.StatusCode);
                    }
                }
            }
        }
        public void Test0030_Register()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                if (!_wpConfig.UseNewSigner)
                {
                    // Re-use existing Signer config from stable local store
                    using (var fs = new FileStream(_testRegister_AcmeSignerFile, FileMode.Open))
                    {
                        signer.Load(fs);
                    }
                }
                _testRegister_AcmeSignerFile = $"{_baseLocalStore}\\TestRegister.acmeSigner";
                using (var fs = new FileStream(_testRegister_AcmeSignerFile, FileMode.Create))
                {
                    signer.Save(fs);
                }

                using (var client = BuildClient(testTagHeader: nameof(Test0030_Register)))
                {
                    client.RootUrl = _rootUrl;
                    client.Signer = signer;
                    client.Init();

                    client.GetDirectory(true);

                    client.Register(new string[] { TEST_EM1, TEST_PH1, });

                    Assert.IsNotNull(client.Registration);
                    Assert.IsFalse(string.IsNullOrWhiteSpace(client.Registration.RegistrationUri));

                    _testRegister_AcmeRegFile = $"{_baseLocalStore}\\TestRegister.acmeReg";
                    using (var fs = new FileStream(_testRegister_AcmeRegFile, FileMode.Create))
                    {
                        client.Registration.Save(fs);
                    }
                }
            }
        }
        public void Test0060_RegisterUpdateContacts()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeSigner", FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeReg", FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient())
                {
                    client.RootUrl = _rootUrl;
                    client.Signer = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    client.UpdateRegistration(true, contacts: new string[] { TEST_EM2, });

                    Assert.IsNotNull(client.Registration);
                    Assert.IsFalse(string.IsNullOrWhiteSpace(client.Registration.RegistrationUri));

                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegisterUpdate.acmeReg", FileMode.Create))
                    {
                        client.Registration.Save(fs);
                    }
                }
            }
        }
Exemplo n.º 47
0
        public void Test0170_GenCsrAndRequestCertificate()
        {
            using (var cp = CertificateProvider.GetProvider())
            {
                var rsaKeyParams = new RsaPrivateKeyParams();
                var rsaKey       = cp.GeneratePrivateKey(rsaKeyParams);

                _testGenCsr_RsaKeysFile = $"{_baseLocalStore}\\TestGenCsr-rsaKeys.txt";
                using (var fs = new FileStream(_testGenCsr_RsaKeysFile, FileMode.Create))
                {
                    cp.SavePrivateKey(rsaKey, fs);
                }

                var csrParams = new CsrParams
                {
                    Details = new CsrDetails
                    {
                        CommonName = TEST_CN1
                    }
                };

                var csr = cp.GenerateCsr(csrParams, rsaKey, Crt.MessageDigest.SHA256);
                _testGenCsr_CsrDetailsFile = $"{_baseLocalStore}\\TestGenCsr-csrDetails.txt";
                using (var fs = new FileStream(_testGenCsr_CsrDetailsFile, FileMode.Create))
                {
                    cp.SaveCsrParams(csrParams, fs);
                }
                _testGenCsr_CsrFile = $"{_baseLocalStore}\\TestGenCsr-csr.txt";
                using (var fs = new FileStream(_testGenCsr_CsrFile, FileMode.Create))
                {
                    cp.SaveCsr(csr, fs);
                }

                using (var signer = new RS256Signer())
                {
                    signer.Init();
                    using (var fs = new FileStream(_testRegister_AcmeSignerFile, FileMode.Open))
                    {
                        signer.Load(fs);
                    }

                    AcmeRegistration reg;
                    using (var fs = new FileStream(_testRegister_AcmeRegFile, FileMode.Open))
                    {
                        reg = AcmeRegistration.Load(fs);
                    }

                    byte[] derRaw;
                    using (var bs = new MemoryStream())
                    {
                        cp.ExportCsr(csr, EncodingFormat.DER, bs);
                        derRaw = bs.ToArray();
                    }
                    var derB64u = JwsHelper.Base64UrlEncode(derRaw);

                    using (var client = BuildClient(testTagHeader: nameof(Test0170_GenCsrAndRequestCertificate)))
                    {
                        client.RootUrl      = _rootUrl;
                        client.Signer       = signer;
                        client.Registration = reg;
                        client.Init();

                        client.GetDirectory(true);

                        var certRequ = client.RequestCertificate(derB64u);

                        _testCertRequ_AcmeCertRequFile = $"{_baseLocalStore}\\TestCertRequ.acmeCertRequ";
                        using (var fs = new FileStream(_testCertRequ_AcmeCertRequFile, FileMode.Create))
                        {
                            certRequ.Save(fs);
                        }
                    }
                }
            }
        }
Exemplo n.º 48
0
        private bool Worker()
        {
            Log("RefreshCertificate start");
            if (!IsAdministrator())
            {
                Log("\tThis program must be run as administrator");
                Log("RefreshCertificate ended");
                return(false);
            }

            // Get all Binding from the different IIS servers, if any
            var sites = GetSiteBindings();

            if (System.Diagnostics.Debugger.IsAttached)
            {
                sites.RemoveRange(1, sites.Count - 1);                 // only use the first one
            }
            RemoveValidWebsites(sites);
            if (sites.Count == 0)
            {
                Log("RefreshCertificate ended");
                return(false);
            }

            var contacts = Properties.Settings.Default.Contacts.Cast <string>().Select(x => "mailto:" + x).ToArray();

            using (var signer = new RS256Signer())
            {
                signer.Init();

                var signerPath = "RSAKeyValue.xml";
                if (File.Exists(signerPath))
                {
                    using (var signerStream = File.OpenRead(signerPath))
                        signer.Load(signerStream);
                    Log("\tLoaded existing {0}", signerPath);
                }
                using (this.client = new AcmeClient(this.BaseUri, new AcmeServerDirectory(), signer))
                {
                    this.client.Init();
                    this.client.GetDirectory(true);

                    var registrationPath = "Registration.json";
                    if (File.Exists(registrationPath))
                    {
                        using (var registrationStream = File.OpenRead(registrationPath))
                            this.client.Registration = AcmeRegistration.Load(registrationStream);

                        Log("\tLoaded existing {0}", registrationPath);
                    }
                    else
                    {
                        var registration = this.client.Register(contacts);

                        this.client.UpdateRegistration(true, true);
                        using (var registrationStream = File.OpenWrite(registrationPath))
                            this.client.Registration.Save(registrationStream);

                        Log("\tCreated new {0}", registrationPath);

                        using (var signerStream = File.OpenWrite(signerPath))
                            signer.Save(signerStream);

                        Log("\tCreated new {0}", signerPath);
                    }

                    // ACME client is now loaded using signer and registration
                    ChallengeGetCertAndInstall(sites);
                }
            }

            Log("RefreshCertificate ended");
            return(true);
        }
Exemplo n.º 49
0
        internal bool MakeCertificate()
        {
            try
            {
                using (var signer = new RS256Signer())
                {
                    signer.Init();

                    var signerPath = Path.Combine(configPath, "Signer");
                    if (File.Exists(signerPath))
                    {
                        logger.Debug("Loading Signer from {0}", signerPath);
                        using (var signerStream = File.OpenRead(signerPath))
                        {
                            signer.Load(signerStream);
                        }
                    }

                    using (client = new AcmeClient(new Uri(acmeUri), new AcmeServerDirectory(), signer))
                    {
                        client.Init();
                        client.GetDirectory(true);

                        var registrationPath = Path.Combine(configPath, "Registration");
                        if (File.Exists(registrationPath))
                        {
                            logger.Debug("Loading Registration from {0}", registrationPath);
                            using (var registrationStream = File.OpenRead(registrationPath))
                            {
                                client.Registration = AcmeRegistration.Load(registrationStream);
                            }
                        }
                        else
                        {
                            var email        = "mailto:" + contactEmail;
                            var registration = client.Register(new string[] { email });

                            client.UpdateRegistration(true, true);

                            using (var registrationStream = File.OpenWrite(registrationPath))
                            {
                                client.Registration.Save(registrationStream);
                            }

                            using (var signerStream = File.OpenWrite(signerPath))
                            {
                                signer.Save(signerStream);
                            }
                        }

                        List <AuthorizationState> authStatus = Authorize();

                        if (authStatus.Any(a => a.Status == "invalid"))
                        {
                            return(false);
                        }

                        PathToCertificate = RequestCertificate();
                    }
                }
            }
            catch (Exception e)
            {
                if (e is AcmeClient.AcmeWebException acmeWebException)
                {
                    logger.Fatal(acmeWebException.Message);
                    logger.Fatal("ACME Server Returned: {0}", acmeWebException.Response.ContentAsString);
                }
                else
                {
                    logger.Fatal(e);
                }

                return(false);
            }

            return(true);
        }
        public void Test0040_RegisterEmptyUpdate()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeSigner", FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeReg", FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient())
                {
                    client.RootUrl = _rootUrl;
                    client.Signer = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    // Do a simple update with no data changes requested
                    client.UpdateRegistration(true);

                    Assert.IsNotNull(client.Registration);
                    Assert.IsFalse(string.IsNullOrWhiteSpace(client.Registration.RegistrationUri));

                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegisterUpdate.acmeReg", FileMode.Create))
                    {
                        client.Registration.Save(fs);
                    }
                }
            }
        }
Exemplo n.º 51
0
        static void Main(string[] args)
        {
            var commandLineParseResult = Parser.Default.ParseArguments <Options>(args);
            var parsed = commandLineParseResult as Parsed <Options>;

            if (parsed == null)
            {
#if DEBUG
                Console.WriteLine("Press enter to continue.");
                Console.ReadLine();
#endif
                return; // not parsed
            }
            Options = parsed.Value;

            Console.WriteLine("Let's Encrypt (Simple Windows ACME Client)");

            BaseURI = Options.BaseURI;
            if (Options.Test)
            {
                BaseURI = "https://acme-staging.api.letsencrypt.org/";
            }

            //Console.Write("\nUse production Let's Encrypt server? (Y/N) ");
            //if (PromptYesNo())
            //    BaseURI = ProductionBaseURI;

            Console.WriteLine($"\nACME Server: {BaseURI}");

            if (!string.IsNullOrWhiteSpace(Options.CentralSSLStore))
            {
                Console.WriteLine("Using Centralized SSL Path: " + Options.CentralSSLStore);
                CentralSSL = true;
            }

            settings = new Settings(clientName, BaseURI);

            configPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), clientName, CleanFileName(BaseURI));
            Console.WriteLine("Config Folder: " + configPath);
            Directory.CreateDirectory(configPath);

            try
            {
                using (var signer = new RS256Signer())
                {
                    signer.Init();

                    var signerPath = Path.Combine(configPath, "Signer");
                    if (File.Exists(signerPath))
                    {
                        Console.WriteLine($"Loading Signer from {signerPath}");
                        using (var signerStream = File.OpenRead(signerPath))
                            signer.Load(signerStream);
                    }

                    using (client = new AcmeClient(new Uri(BaseURI), new AcmeServerDirectory(), signer))
                    {
                        client.Init();
                        Console.WriteLine("\nGetting AcmeServerDirectory");
                        client.GetDirectory(true);

                        var registrationPath = Path.Combine(configPath, "Registration");
                        if (File.Exists(registrationPath))
                        {
                            Console.WriteLine($"Loading Registration from {registrationPath}");
                            using (var registrationStream = File.OpenRead(registrationPath))
                                client.Registration = AcmeRegistration.Load(registrationStream);
                        }
                        else
                        {
                            Console.Write("Enter an email address (not public, used for renewal fail notices): ");
                            var email = Console.ReadLine().Trim();

                            var contacts = new string[] { };
                            if (!String.IsNullOrEmpty(email))
                            {
                                email    = "mailto:" + email;
                                contacts = new string[] { email };
                            }

                            Console.WriteLine("Calling Register");
                            var registration = client.Register(contacts);

                            if (!Options.AcceptTOS && !Options.Renew)
                            {
                                Console.WriteLine($"Do you agree to {registration.TosLinkUri}? (Y/N) ");
                                if (!PromptYesNo())
                                {
                                    return;
                                }
                            }

                            Console.WriteLine("Updating Registration");
                            client.UpdateRegistration(true, true);

                            Console.WriteLine("Saving Registration");
                            using (var registrationStream = File.OpenWrite(registrationPath))
                                client.Registration.Save(registrationStream);

                            Console.WriteLine("Saving Signer");
                            using (var signerStream = File.OpenWrite(signerPath))
                                signer.Save(signerStream);
                        }

                        if (Options.Renew)
                        {
                            CheckRenewals();
#if DEBUG
                            Console.WriteLine("Press enter to continue.");
                            Console.ReadLine();
#endif
                            return;
                        }

                        var targets = new List <Target>();
                        foreach (var plugin in Target.Plugins.Values)
                        {
                            targets.AddRange(plugin.GetTargets());
                        }

                        if (targets.Count == 0)
                        {
                            Console.WriteLine("No targets found.");
                        }
                        else
                        {
                            var count = 1;
                            foreach (var binding in targets)
                            {
                                Console.WriteLine($" {count}: {binding}");
                                count++;
                            }
                        }

                        Console.WriteLine();
                        foreach (var plugin in Target.Plugins.Values)
                        {
                            plugin.PrintMenu();
                        }

                        Console.WriteLine(" A: Get certificates for all hosts");
                        Console.WriteLine(" Q: Quit");
                        Console.Write("Which host do you want to get a certificate for: ");
                        var response = Console.ReadLine().ToLowerInvariant();
                        switch (response)
                        {
                        case "a":
                            foreach (var target in targets)
                            {
                                Auto(target);
                            }
                            break;

                        case "q":
                            return;

                        default:
                            var targetId = 0;
                            if (Int32.TryParse(response, out targetId))
                            {
                                targetId--;
                                if (targetId >= 0 && targetId < targets.Count)
                                {
                                    var binding = targets[targetId];
                                    Auto(binding);
                                }
                            }
                            else
                            {
                                foreach (var plugin in Target.Plugins.Values)
                                {
                                    plugin.HandleMenuResponse(response, targets);
                                }
                            }
                            break;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                var acmeWebException = e as AcmeClient.AcmeWebException;
                if (acmeWebException != null)
                {
                    Console.WriteLine(acmeWebException.Message);
                    Console.WriteLine("ACME Server Returned:");
                    Console.WriteLine(acmeWebException.Response.ContentAsString);
                }
                else
                {
                    Console.WriteLine(e);
                }
                Console.ResetColor();
            }

            Console.WriteLine("Press enter to continue.");
            Console.ReadLine();
        }
        public void Test0146_SubmitHttpChallengeAnswers()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream(_testRegister_AcmeSignerFile, FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream(_testRegister_AcmeRegFile, FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient(testTagHeader: nameof(Test0146_SubmitHttpChallengeAnswers)))
                {
                    client.RootUrl = _rootUrl;
                    client.Signer = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    AuthorizationState authzState;
                    using (var fs = new FileStream(_testAuthzChallengeHttpHandled_AcmeAuthzFile, FileMode.Open))
                    {
                        authzState = AuthorizationState.Load(fs);
                    }

                    client.GenerateAuthorizeChallengeAnswer(authzState, AcmeProtocol.CHALLENGE_TYPE_HTTP);
                    client.SubmitAuthorizeChallengeAnswer(authzState, AcmeProtocol.CHALLENGE_TYPE_HTTP, true);

                    _testAuthzChallengeHttpAnswered_AcmeAuthzFile = $"{_baseLocalStore}\\TestAuthz-HttpChallengeAnswered.acmeAuthz";
                    using (var fs = new FileStream(_testAuthzChallengeHttpAnswered_AcmeAuthzFile, FileMode.Create))
                    {
                        authzState.Save(fs);
                    }
                }
            }
        }
        public void Test0141_HandleHttpChallenge()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream(_testRegister_AcmeSignerFile, FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream(_testRegister_AcmeRegFile, FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient(testTagHeader: nameof(Test0141_HandleHttpChallenge)))
                {
                    client.RootUrl = _rootUrl;
                    client.Signer = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    AuthorizationState authzState;
                    using (var fs = new FileStream(_testAuthz_AcmeAuthzFile, FileMode.Open))
                    {
                        authzState = AuthorizationState.Load(fs);
                    }

                    var authzChallenge = client.GenerateAuthorizeChallengeAnswer(authzState, AcmeProtocol.CHALLENGE_TYPE_HTTP);
                    _testAuthzChallengeHttpHandled_AcmeAuthzFile = $"{_baseLocalStore}\\TestAuthz-ChallengeAnswersHandleHttp.acmeAuthz";
                    using (var fs = new FileStream(_testAuthzChallengeHttpHandled_AcmeAuthzFile, FileMode.Create))
                    {
                        authzState.Save(fs);
                    }

                    var wsFilePath = authzChallenge.ChallengeAnswer.Key;
                    var wsFileBody = authzChallenge.ChallengeAnswer.Value;

                    var wsInfo = WebServerInfo.Load(File.ReadAllText("webServerInfo.json"));
                    using (var s = new MemoryStream(Encoding.UTF8.GetBytes(wsFileBody)))
                    {
                        var fileUrl = new Uri($"http://{authzState.Identifier}/{wsFilePath}");
                        wsInfo.Provider.UploadFile(fileUrl, s);
                    }
                }
            }

            Thread.Sleep(90 * 1000);
        }
        public void Test0145_SubmitHttpChallengeAnswers()
        {
            using (var signer = new RS256Signer())
            {
                signer.Init();
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeSigner", FileMode.Open))
                {
                    signer.Load(fs);
                }

                AcmeRegistration reg;
                using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeReg", FileMode.Open))
                {
                    reg = AcmeRegistration.Load(fs);
                }

                using (var client = BuildClient())
                {
                    client.RootUrl = _rootUrl;
                    client.Signer = signer;
                    client.Registration = reg;
                    client.Init();

                    client.GetDirectory(true);

                    AuthorizationState authzState;
                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz-ChallengeAnswersHandleHttp.acmeAuthz", FileMode.Open))
                    {
                        authzState = AuthorizationState.Load(fs);
                    }

                    client.GenerateAuthorizeChallengeAnswer(authzState, "simpleHttp");
                    client.SubmitAuthorizeChallengeAnswer(authzState, "simpleHttp", true);

                    using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz-HttpChallengeAnswered.acmeAuthz", FileMode.Create))
                    {
                        authzState.Save(fs);
                    }
                }
            }
        }