示例#1
0
        public void POST_Nonce_Empty()
        {
            AcmeResponse response = null;

            using var provider = Application.CreateProvider();
            IAcmeController controller = (IAcmeController)provider.GetService(typeof(IAcmeController));

            var accountKey = RSA.Create(2048);
            var token      = new JsonWebSignature();

            token.SetProtected(new JsonWebSignatureProtected
            {
                Url       = $"{Application.BaseAddress}new-acct",
                Algorithm = AlgorithmsEnum.RS256,
                Key       = new JsonWebKey(accountKey),
            });
            token.Sign(accountKey);

            response = controller.CreateAccount(new AcmeRequest
            {
                Path   = $"{Application.BaseAddress}new-acct",
                Method = "POST",
                Token  = token,
            });

            Assert.Equal(400, response.StatusCode);

            var content = response.GetContent <Protocol.Error>();

            Assert.Equal(Protocol.ErrorType.Malformed, content.Type);
            Assert.NotNull(content.Detail);
        }
示例#2
0
        public void Account_New_TermsOfService_Enabled_TermsOfServiceAgreed_False()
        {
            AcmeResponse response = null;

            using var provider = Application.CreateProvider(o =>
            {
                o.TermsOfService = "https://some.com/acme/terms.pdf";
            });
            IAcmeController controller = (IAcmeController)provider.GetService(typeof(IAcmeController));

            // Get nonce
            response = controller.GetNonce(new AcmeRequest
            {
                Path   = $"{Application.BaseAddress}new-nonce",
                Method = "HEAD",
            });

            // Create token
            var accountKey = RSA.Create(2048);
            var token      = new JsonWebSignature();

            token.SetProtected(new JsonWebSignatureProtected
            {
                Url       = $"{Application.BaseAddress}new-acct",
                Algorithm = AlgorithmsEnum.RS256,
                Key       = new JsonWebKey(accountKey),
                Nonce     = response.Headers.ReplayNonce,
            });
            token.SetPayload(new NewAccount
            {
                Contacts             = new string[] { "mailto:[email protected]" },
                TermsOfServiceAgreed = false,
            });
            token.Sign(accountKey);

            // Create account
            response = controller.CreateAccount(new AcmeRequest
            {
                Path   = $"{Application.BaseAddress}new-acct",
                Method = "POST",
                Token  = token,
            });

            Assert.Equal(400, response.StatusCode);

            var content = response.GetContent <Protocol.Error>();

            Assert.Equal(Protocol.ErrorType.Malformed, content.Type);
            Assert.NotNull(content.Detail);
        }
示例#3
0
        public void Account_New_TermsOfService_Disabled()
        {
            AcmeResponse response = null;

            using var provider = Application.CreateProvider();
            IAcmeController controller = (IAcmeController)provider.GetService(typeof(IAcmeController));

            // Get nonce
            response = controller.GetNonce(new AcmeRequest
            {
                Path   = $"{Application.BaseAddress}new-nonce",
                Method = "HEAD",
            });

            // Create token
            var accountKey = RSA.Create(2048);
            var token      = new JsonWebSignature();

            token.SetProtected(new JsonWebSignatureProtected
            {
                Url       = $"{Application.BaseAddress}new-acct",
                Algorithm = AlgorithmsEnum.RS256,
                Key       = new JsonWebKey(accountKey),
                Nonce     = response.Headers.ReplayNonce,
            });
            token.SetPayload(new NewAccount
            {
                Contacts = new string[] { "mailto:[email protected]" },
            });
            token.Sign(accountKey);

            // Create account
            response = controller.CreateAccount(new AcmeRequest
            {
                Path   = $"{Application.BaseAddress}new-acct",
                Method = "POST",
                Token  = token,
            });

            Assert.Equal(201, response.StatusCode);

            var content = response.GetContent <Protocol.Account>();

            Assert.Single(response.Headers.Link);
            Assert.Equal("https://test.server.com/acme/acct/1", response.Headers.Location);
            Assert.NotNull(content);
            Assert.NotNull(content.Key);
            Assert.Null(content.TermsOfServiceAgreed);
        }
示例#4
0
        public void Nonce_Head()
        {
            using var provider = Application.CreateProvider();
            IAcmeController controller = (IAcmeController)provider.GetService(typeof(IAcmeController));

            var response = controller.GetNonce(new AcmeRequest
            {
                Path   = $"{Application.BaseAddress}new-nonce",
                Method = "HEAD",
            });

            // The server's response MUST include a Replay-
            // Nonce header field containing a fresh nonce and SHOULD have status
            // code 200(OK)
            Assert.Equal(200, response.StatusCode);
            Assert.NotNull(response.Headers.ReplayNonce);
        }
示例#5
0
        public void Nonce_Get()
        {
            using var provider = Application.CreateProvider();
            IAcmeController controller = (IAcmeController)provider.GetService(typeof(IAcmeController));

            var response = controller.GetNonce(new AcmeRequest
            {
                Path   = $"{Application.BaseAddress}new-nonce",
                Method = "GET",
            });

            // The server MUST also respond to GET requests for this
            // resource, returning an empty body(while still providing a Replay -
            // Nonce header) with a status code of 204(No Content)
            Assert.Equal(204, response.StatusCode);
            Assert.NotNull(response.Headers.ReplayNonce);
        }
示例#6
0
        public void POST_Url_WrongTargetUrl()
        {
            /// The value of the "url" header
            /// parameter MUST be a string representing the target URL

            AcmeResponse response = null;

            using var provider = Application.CreateProvider();
            IAcmeController controller = (IAcmeController)provider.GetService(typeof(IAcmeController));

            // Get nonce
            response = controller.GetNonce(new AcmeRequest
            {
                Path   = $"{Application.BaseAddress}new-nonce",
                Method = "HEAD",
            });

            var accountKey = RSA.Create(2048);
            var token      = new JsonWebSignature();

            token.SetProtected(new JsonWebSignatureProtected
            {
                Url       = "https://wrong.com/acme/new-account",
                Nonce     = response.Headers.ReplayNonce,
                Algorithm = AlgorithmsEnum.RS256,
                Key       = new JsonWebKey(accountKey),
            });
            token.Sign(accountKey);

            response = controller.CreateAccount(new AcmeRequest
            {
                Path   = $"{Application.BaseAddress}new-acct",
                Method = "POST",
                Token  = token,
            });

            Assert.Equal(400, response.StatusCode);

            var content = response.GetContent <Protocol.Error>();

            Assert.Equal(Protocol.ErrorType.Malformed, content.Type);
            Assert.NotNull(content.Detail);
        }
示例#7
0
        public void Directory_GeMetadata()
        {
            using var provider = Application.CreateProvider(o =>
            {
                o.BaseAddress = Application.BaseAddress;
                o.ExternalAccountOptions.Type = ExternalAccountType.Required;
            });
            IAcmeController controller = (IAcmeController)provider.GetService(typeof(IAcmeController));

            var response = controller.GetDirectory(new AcmeRequest
            {
                Path   = $"{Application.BaseAddress}directory",
                Method = "GET",
            });

            var content = response.GetContent <Protocol.Directory>();

            Assert.NotNull(content.Meta);
            Assert.Equal(true, content.Meta.ExternalAccountRequired);
        }
示例#8
0
        public void Directory_Get()
        {
            using var provider = Application.CreateProvider();
            IAcmeController controller = (IAcmeController)provider.GetService(typeof(IAcmeController));

            var response = controller.GetDirectory(new AcmeRequest
            {
                Path   = $"{Application.BaseAddress}directory",
                Method = "GET",
            });

            var content = response.GetContent <Protocol.Directory>();

            Assert.Equal($"{Application.BaseAddress}new-nonce", content.NewNonce);
            Assert.Equal($"{Application.BaseAddress}new-acct", content.NewAccount);
            Assert.Equal($"{Application.BaseAddress}new-order", content.NewOrder);
            // TODO Assert.Equal($"{Application.BaseAddress}new-authz", content.NewAuthz);
            Assert.Equal($"{Application.BaseAddress}revoke", content.RevokeCertificate);
            Assert.Equal($"{Application.BaseAddress}key-change", content.KeyChange);
            Assert.Null(content.Meta);
        }
示例#9
0
        public void POST_Nonce_WrongEncoding()
        {
            AcmeResponse response = null;

            using var provider = Application.CreateProvider();
            IAcmeController controller = (IAcmeController)provider.GetService(typeof(IAcmeController));

            var accountKey = RSA.Create(2048);
            var token      = new JsonWebSignature();

            token.SetProtected(new JsonWebSignatureProtected
            {
                Url       = $"{Application.BaseAddress}new-acct",
                Algorithm = AlgorithmsEnum.RS256,
                Key       = new JsonWebKey(accountKey),
                Nonce     = "Wrong encoded nonce"
            });
            token.Sign(accountKey);

            response = controller.CreateAccount(new AcmeRequest
            {
                Path   = $"{Application.BaseAddress}new-acct",
                Method = "POST",
                Token  = token,
            });

            // If the value of a "nonce" header parameter is not valid
            // according to this encoding, then the verifier MUST reject the JWS as
            // malformed.
            Assert.Equal(400, response.StatusCode);

            var content = response.GetContent <Protocol.Error>();

            Assert.Equal(Protocol.ErrorType.Malformed, content.Type);
            Assert.NotNull(content.Detail);
        }
示例#10
0
 public AcmeController(IAcmeController controller)
 {
     Controller = controller ?? throw new ArgumentNullException(nameof(controller));
 }
示例#11
0
        public void Account_ChangeKey_DuplicateKey()
        {
            AcmeResponse response = null;

            using var provider = Application.CreateProvider();
            IAcmeController controller = (IAcmeController)provider.GetService(typeof(IAcmeController));

            // Get nonce
            response = controller.GetNonce(new AcmeRequest
            {
                Path   = $"{Application.BaseAddress}new-nonce",
                Method = "HEAD",
            });

            // Create token
            var accountKey = RSA.Create(2048);
            var token      = new JsonWebSignature();

            token.SetProtected(new JsonWebSignatureProtected
            {
                Url       = $"{Application.BaseAddress}new-acct",
                Algorithm = AlgorithmsEnum.RS256,
                Key       = new JsonWebKey(accountKey),
                Nonce     = response.Headers.ReplayNonce,
            });
            token.SetPayload(new NewAccount
            {
                Contacts = new string[] { "mailto:[email protected]" },
            });
            token.Sign(accountKey);

            // Create account
            response = controller.CreateAccount(new AcmeRequest
            {
                Path   = $"{Application.BaseAddress}new-acct",
                Method = "POST",
                Token  = token,
            });

            Assert.Equal(201, response.StatusCode);

            // Create token
            var duplicateKey = RSA.Create(2048);

            token = new JsonWebSignature();
            token.SetProtected(new JsonWebSignatureProtected
            {
                Url       = $"{Application.BaseAddress}new-acct",
                Algorithm = AlgorithmsEnum.RS256,
                Key       = new JsonWebKey(duplicateKey),
                Nonce     = response.Headers.ReplayNonce,
            });
            token.SetPayload(new NewAccount
            {
                Contacts = new string[] { "mailto:[email protected]" },
            });
            token.Sign(duplicateKey);

            // Create account
            response = controller.CreateAccount(new AcmeRequest
            {
                Path   = $"{Application.BaseAddress}new-acct",
                Method = "POST",
                Token  = token,
            });

            Assert.Equal(201, response.StatusCode);

            token = new JsonWebSignature();
            token.SetProtected(new JsonWebSignatureProtected
            {
                Url       = $"{Application.BaseAddress}key-change",
                Algorithm = AlgorithmsEnum.RS256,
                KeyID     = $"{Application.BaseAddress}acct/1",
                Nonce     = response.Headers.ReplayNonce,
            });
            #region New key
            var newKeyToken = new JsonWebSignature();
            newKeyToken.SetProtected(new JsonWebSignatureProtected
            {
                Url       = $"{Application.BaseAddress}key-change",
                Algorithm = AlgorithmsEnum.RS256,
                Key       = new JsonWebKey(duplicateKey),
            });
            newKeyToken.SetPayload(new ChangeKey
            {
                Account = $"{Application.BaseAddress}acct/1",
                Key     = new JsonWebKey(accountKey),
            });
            newKeyToken.Sign(duplicateKey);
            #endregion

            token.SetPayload(newKeyToken);
            token.Sign(accountKey);

            // Update account
            response = controller.ChangeKey(new AcmeRequest
            {
                Path   = $"{Application.BaseAddress}key-change",
                Method = "POST",
                Token  = token,
            });

            Assert.Equal(409, response.StatusCode);
            Assert.Equal($"{Application.BaseAddress}acct/2", response.Headers.Location);

            var content = response.GetContent <Protocol.Error>();
            Assert.Equal(Protocol.ErrorType.Malformed, content.Type);
            Assert.NotNull(content.Detail);
        }
示例#12
0
        public void Account_Deactivate()
        {
            AcmeResponse response = null;

            using var provider = Application.CreateProvider();
            IAcmeController controller = (IAcmeController)provider.GetService(typeof(IAcmeController));

            // Get nonce
            response = controller.GetNonce(new AcmeRequest
            {
                Path   = $"{Application.BaseAddress}new-nonce",
                Method = "HEAD",
            });

            // Create token
            var accountKey = RSA.Create(2048);
            var token      = new JsonWebSignature();

            token.SetProtected(new JsonWebSignatureProtected
            {
                Url       = $"{Application.BaseAddress}new-acct",
                Algorithm = AlgorithmsEnum.RS256,
                Key       = new JsonWebKey(accountKey),
                Nonce     = response.Headers.ReplayNonce,
            });
            token.SetPayload(new NewAccount
            {
                Contacts = new string[] { "mailto:[email protected]" },
            });
            token.Sign(accountKey);

            // Create account
            response = controller.CreateAccount(new AcmeRequest
            {
                Path   = $"{Application.BaseAddress}new-acct",
                Method = "POST",
                Token  = token,
            });

            Assert.Equal(201, response.StatusCode);

            token = new JsonWebSignature();
            token.SetProtected(new JsonWebSignatureProtected
            {
                Url       = response.Headers.Location,
                Algorithm = AlgorithmsEnum.RS256,
                KeyID     = response.Headers.Location,
                Nonce     = response.Headers.ReplayNonce,
            });
            token.SetPayload(new UpdateAccount
            {
                Contacts = new string[] { "mailto:[email protected]" },
                Status   = Protocol.AccountStatus.Deactivated,
            });
            token.Sign(accountKey);

            // Update account
            response = controller.PostAccount(new AcmeRequest
            {
                Path   = response.Headers.Location,
                Method = "POST",
                Token  = token,
            });

            Assert.Equal(200, response.StatusCode);

            var content = response.GetContent <Protocol.Account>();

            Assert.Equal("mailto:[email protected]", content.Contacts[0]);
            Assert.Equal(Protocol.AccountStatus.Deactivated, content.Status);
        }