コード例 #1
0
ファイル: AcmeClient.cs プロジェクト: bcooper0/ACMESharp
        public AcmeRegistration Register(string[] contacts)
        {
            AssertInit();

            var requMsg = new NewRegRequest
            {
                Contact = contacts,
            };

            var resp = RequestHttpPost(new Uri(RootUrl,
                                               Directory[AcmeServerDirectory.RES_NEW_REG]), requMsg);

            // HTTP 409 (Conflict) response for a previously registered pub key
            //    Location:  still had the regUri
            if (resp.IsError)
            {
                if (resp.StatusCode == HttpStatusCode.Conflict)
                {
                    throw new AcmeWebException(resp.Error as WebException,
                                               "Conflict due to previously registered public key", resp);
                }
                else if (resp.IsError)
                {
                    throw new AcmeWebException(resp.Error as WebException,
                                               "Unexpected error", resp);
                }
            }

            var regUri = resp.Headers[AcmeProtocol.HEADER_LOCATION];

            if (string.IsNullOrEmpty(regUri))
            {
                throw new AcmeException("server did not provide a registration URI in the response");
            }

            var respMsg = JsonConvert.DeserializeObject <RegResponse>(resp.ContentAsString);

            var newReg = new AcmeRegistration
            {
                PublicKey       = Signer.ExportJwk(),
                RegistrationUri = regUri,
                Contacts        = respMsg.Contact,
                Links           = resp.Links,
                /// Extracts the "Terms of Service" related link header if there is one and
                /// returns the URI associated with it.  Otherwise returns <c>null</c>.
                TosLinkUri        = resp.Links[AcmeProtocol.LINK_HEADER_REL_TOS].FirstOrDefault(),
                AuthorizationsUri = respMsg.Authorizations,
                CertificatesUri   = respMsg.Certificates,
                TosAgreementUri   = respMsg.Agreement,
            };

            Registration = newReg;

            return(Registration);
        }
コード例 #2
0
ファイル: AcmeClient.cs プロジェクト: bcooper0/ACMESharp
        public AcmeClient(Uri rootUrl    = null, AcmeServerDirectory dir = null,
                          ISigner signer = null, AcmeRegistration reg    = null)
        {
            RootUrl      = rootUrl;
            Directory    = dir;
            Signer       = signer;
            Registration = reg;

            UserAgent = string.Format(AcmeProtocol.HTTP_USER_AGENT_FMT,
                                      this.GetType().Assembly.GetName().Version);
        }
コード例 #3
0
ファイル: AcmeClient.cs プロジェクト: bcooper0/ACMESharp
        public AcmeRegistration UpdateRegistration(bool useRootUrl = false, bool agreeToTos = false, string[] contacts = null)
        {
            AssertInit();
            AssertRegistration();

            var requMsg = new UpdateRegRequest();

            if (contacts != null)
            {
                requMsg.Contact = contacts;
            }

            if (agreeToTos && !string.IsNullOrWhiteSpace(Registration.TosLinkUri))
            {
                requMsg.Agreement = Registration.TosLinkUri;
            }

            // Compute the URL to submit the request to, either exactly as
            // provided in the Registration object or relative to the Root URL
            var requUri = new Uri(Registration.RegistrationUri);

            if (useRootUrl)
            {
                requUri = new Uri(RootUrl, requUri.PathAndQuery);
            }

            var resp = RequestHttpPost(requUri, requMsg);

            if (resp.IsError)
            {
                throw new AcmeWebException(resp.Error as WebException,
                                           "Unexpected error", resp);
            }

            var respMsg = JsonConvert.DeserializeObject <RegResponse>(resp.ContentAsString);

            var updReg = new AcmeRegistration
            {
                PublicKey       = Signer.ExportJwk(),
                RegistrationUri = Registration.RegistrationUri,
                Contacts        = respMsg.Contact,
                Links           = resp.Links,
                /// Extracts the "Terms of Service" related link header if there is one and
                /// returns the URI associated with it.  Otherwise returns <c>null</c>.
                TosLinkUri        = resp.Links[AcmeProtocol.LINK_HEADER_REL_TOS].FirstOrDefault(),
                AuthorizationsUri = respMsg.Authorizations,
                CertificatesUri   = respMsg.Certificates,
                TosAgreementUri   = respMsg.Agreement,
            };

            Registration = updReg;

            return(Registration);
        }
コード例 #4
0
ファイル: AcmeClient.cs プロジェクト: jagbarcelo/ACMESharp
        public AcmeClient(Uri rootUrl = null, AcmeServerDirectory dir = null,
                ISigner signer = null, AcmeRegistration reg = null)
        {
            RootUrl = rootUrl;
            Directory = dir;
            Signer = signer;
            Registration = reg;

            UserAgent = string.Format(AcmeProtocol.HTTP_USER_AGENT_FMT,
                    this.GetType().Assembly.GetName().Version);
        }
コード例 #5
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);
                        }
                    }
                }
            }
        }
コード例 #6
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);
        }
コード例 #7
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);
                    }
                }
            }
        }
コード例 #8
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);
                    }
                }
            }
        }
コード例 #9
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);
                    }
                }
            }
        }
コード例 #10
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");
                    }
                }
            }
        }
コード例 #11
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);
                    }
                }
            }
        }
コード例 #12
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);
                    }
                }
            }
        }
コード例 #13
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);
                    }
                }
            }
        }
コード例 #14
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);
                        }
                    }
                }
            }
        }
コード例 #15
0
ファイル: AcmeClient.cs プロジェクト: jagbarcelo/ACMESharp
        public AcmeRegistration UpdateRegistration(bool useRootUrl = false, bool agreeToTos = false, string[] contacts = null)
        {
            AssertInit();
            AssertRegistration();

            var requMsg = new UpdateRegRequest();

            if (contacts != null)
                requMsg.Contact = contacts;

            if (agreeToTos && !string.IsNullOrWhiteSpace(Registration.TosLinkUri))
                requMsg.Agreement = Registration.TosLinkUri;

            // Compute the URL to submit the request to, either exactly as
            // provided in the Registration object or relative to the Root URL
            var requUri = new Uri(Registration.RegistrationUri);
            if (useRootUrl)
                requUri = new Uri(RootUrl, requUri.PathAndQuery);

            var resp = RequestHttpPost(requUri, requMsg);

            if (resp.IsError)
            {
                throw new AcmeWebException(resp.Error as WebException,
                        "Unexpected error", resp);
            }

            var respMsg = JsonConvert.DeserializeObject<RegResponse>(resp.ContentAsString);

            var updReg = new AcmeRegistration
            {
                PublicKey = Signer.ExportJwk(),
                RegistrationUri = Registration.RegistrationUri,
                Contacts = respMsg.Contact,
                Links = resp.Links,
                /// Extracts the "Terms of Service" related link header if there is one and
                /// returns the URI associated with it.  Otherwise returns <c>null</c>.
                TosLinkUri = resp.Links[AcmeProtocol.LINK_HEADER_REL_TOS].FirstOrDefault(),
                AuthorizationsUri = respMsg.Authorizations,
                CertificatesUri = respMsg.Certificates,
                TosAgreementUri = respMsg.Agreement,
            };

            Registration = updReg;

            return Registration;
        }
コード例 #16
0
ファイル: AcmeClient.cs プロジェクト: jagbarcelo/ACMESharp
        public AcmeRegistration Register(string[] contacts)
        {
            AssertInit();

            var requMsg = new NewRegRequest
            {
                Contact = contacts,
            };

            var resp = RequestHttpPost(new Uri(RootUrl,
                    Directory[AcmeServerDirectory.RES_NEW_REG]), requMsg);

            // HTTP 409 (Conflict) response for a previously registered pub key
            //    Location:  still had the regUri
            if (resp.IsError)
            {
                if (resp.StatusCode == HttpStatusCode.Conflict)
                    throw new AcmeWebException(resp.Error as WebException,
                            "Conflict due to previously registered public key", resp);
                else if (resp.IsError)
                    throw new AcmeWebException(resp.Error as WebException,
                            "Unexpected error", resp);
            }

            var regUri = resp.Headers[AcmeProtocol.HEADER_LOCATION];
            if (string.IsNullOrEmpty(regUri))
                throw new AcmeException("server did not provide a registration URI in the response");

            var respMsg = JsonConvert.DeserializeObject<RegResponse>(resp.ContentAsString);

            var newReg = new AcmeRegistration
            {
                PublicKey = Signer.ExportJwk(),
                RegistrationUri = regUri,
                Contacts = respMsg.Contact,
                Links = resp.Links,
                /// Extracts the "Terms of Service" related link header if there is one and
                /// returns the URI associated with it.  Otherwise returns <c>null</c>.
                TosLinkUri = resp.Links[AcmeProtocol.LINK_HEADER_REL_TOS].FirstOrDefault(),
                AuthorizationsUri = respMsg.Authorizations,
                CertificatesUri = respMsg.Certificates,
                TosAgreementUri = respMsg.Agreement,
            };

            Registration = newReg;

            return Registration;
        }