Compare commits

...

1168 Commits

Author SHA1 Message Date
github-actions[bot] a85723d9f8
Merge pull request #1897 from smallstep/dependabot/go_modules/google.golang.org/api-0.185.0
Bump google.golang.org/api from 0.184.0 to 0.185.0
16 hours ago
Max c3beeaf44c
Merge branch 'master' into dependabot/go_modules/google.golang.org/api-0.185.0 16 hours ago
github-actions[bot] 367d90d0cc
Merge pull request #1898 from smallstep/dependabot/go_modules/github.com/go-chi/chi/v5-5.0.14
Bump github.com/go-chi/chi/v5 from 5.0.12 to 5.0.14
16 hours ago
dependabot[bot] 27bea359cb
Bump github.com/go-chi/chi/v5 from 5.0.12 to 5.0.14
Bumps [github.com/go-chi/chi/v5](https://github.com/go-chi/chi) from 5.0.12 to 5.0.14.
- [Release notes](https://github.com/go-chi/chi/releases)
- [Changelog](https://github.com/go-chi/chi/blob/master/CHANGELOG.md)
- [Commits](https://github.com/go-chi/chi/compare/v5.0.12...v5.0.14)

---
updated-dependencies:
- dependency-name: github.com/go-chi/chi/v5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
16 hours ago
github-actions[bot] 5eb1849a8f
Merge pull request #1896 from smallstep/dependabot/github_actions/softprops/action-gh-release-2.0.6
Bump softprops/action-gh-release from 2.0.5 to 2.0.6
16 hours ago
Max ee69818c27
Merge branch 'master' into dependabot/go_modules/google.golang.org/api-0.185.0 16 hours ago
github-actions[bot] 7ff52f6e6c
Merge pull request #1899 from smallstep/dependabot/go_modules/github.com/fxamacker/cbor/v2-2.7.0
Bump github.com/fxamacker/cbor/v2 from 2.6.0 to 2.7.0
16 hours ago
Carl Tashian 12c2e75db6
Update goreleaser YML version (#1901)
* Update goreleaser YML version

* Update http-retryable go pkg

---------

Co-authored-by: max furman <mx.furman@gmail.com>
16 hours ago
dependabot[bot] d12d866f84
Bump github.com/fxamacker/cbor/v2 from 2.6.0 to 2.7.0
Bumps [github.com/fxamacker/cbor/v2](https://github.com/fxamacker/cbor) from 2.6.0 to 2.7.0.
- [Release notes](https://github.com/fxamacker/cbor/releases)
- [Commits](https://github.com/fxamacker/cbor/compare/v2.6.0...v2.7.0)

---
updated-dependencies:
- dependency-name: github.com/fxamacker/cbor/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 days ago
dependabot[bot] 43bf6b5a46
Bump google.golang.org/api from 0.184.0 to 0.185.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.184.0 to 0.185.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.184.0...v0.185.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 days ago
dependabot[bot] fffffc60a8
Bump softprops/action-gh-release from 2.0.5 to 2.0.6
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.0.5 to 2.0.6.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](69320dbe05...a74c6b72af)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2 days ago
github-actions[bot] 9bf6a8369f
Merge pull request #1891 from smallstep/dependabot/go_modules/google.golang.org/protobuf-1.34.2
Bump google.golang.org/protobuf from 1.34.1 to 1.34.2
1 week ago
dependabot[bot] 43bdd61803
Bump google.golang.org/protobuf from 1.34.1 to 1.34.2
Bumps google.golang.org/protobuf from 1.34.1 to 1.34.2.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 week ago
github-actions[bot] 1563c264bd
Merge pull request #1890 from smallstep/dependabot/go_modules/google.golang.org/api-0.184.0
Bump google.golang.org/api from 0.183.0 to 0.184.0
1 week ago
github-actions[bot] 14230d8696
Merge pull request #1889 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.47.1
Bump go.step.sm/crypto from 0.47.0 to 0.47.1
1 week ago
dependabot[bot] 958c344f18
Bump google.golang.org/api from 0.183.0 to 0.184.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.183.0 to 0.184.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.183.0...v0.184.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 week ago
dependabot[bot] 8a7892463d
Bump go.step.sm/crypto from 0.47.0 to 0.47.1
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.47.0 to 0.47.1.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.47.0...v0.47.1)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 week ago
Max 890e81cb66
[actions] dependabot to common workflow | move to new release action (#1887) 2 weeks ago
github-actions[bot] 2d4bc95460
Merge pull request #1883 from smallstep/dependabot/go_modules/github.com/Azure/azure-sdk-for-go/sdk/azidentity-1.6.0
Bump github.com/Azure/azure-sdk-for-go/sdk/azidentity from 1.5.2 to 1.6.0
2 weeks ago
Max 93ca1e21c1
Merge branch 'master' into dependabot/go_modules/github.com/Azure/azure-sdk-for-go/sdk/azidentity-1.6.0 2 weeks ago
Max d6973c979e
Set date for 0.26.2 release in changelog (#1886) 2 weeks ago
Max d4b2916650
Changelog update for 0.26.2 (#1885) 2 weeks ago
Mariano Cano f9e5971978
Merge pull request #1884 from smallstep/mariano/linkedca
Upgrade linkedca
2 weeks ago
Mariano Cano c8e65abfb1
Fix linter warnings 2 weeks ago
Mariano Cano b4616ee8f1
Upgrade linkedca
This commit upgrades go.step.sm/linkedca with dependencies required by
smallstep/certificates#1802. It also fixes some linter warnings.
2 weeks ago
Mariano Cano 634ece4489
Merge pull request #1802 from jdoupe/AuthParams
add AuthParams to OIDC struct
2 weeks ago
Mariano Cano a017c0e3fb
Merge branch 'master' into AuthParams 2 weeks ago
dependabot[bot] 7bc9d15849
Bump github.com/Azure/azure-sdk-for-go/sdk/azidentity
Bumps [github.com/Azure/azure-sdk-for-go/sdk/azidentity](https://github.com/Azure/azure-sdk-for-go) from 1.5.2 to 1.6.0.
- [Release notes](https://github.com/Azure/azure-sdk-for-go/releases)
- [Changelog](https://github.com/Azure/azure-sdk-for-go/blob/main/documentation/release.md)
- [Commits](https://github.com/Azure/azure-sdk-for-go/compare/sdk/internal/v1.5.2...sdk/azcore/v1.6.0)

---
updated-dependencies:
- dependency-name: github.com/Azure/azure-sdk-for-go/sdk/azidentity
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2 weeks ago
github-actions[bot] 8b36f7bc11
Merge pull request #1878 from smallstep/dependabot/go_modules/google.golang.org/api-0.183.0
Bump google.golang.org/api from 0.182.0 to 0.183.0
2 weeks ago
Max 30b2cd1e5c
Merge branch 'master' into dependabot/go_modules/google.golang.org/api-0.183.0 2 weeks ago
github-actions[bot] a0b9360725
Merge pull request #1879 from smallstep/dependabot/go_modules/golang.org/x/crypto-0.24.0
Bump golang.org/x/crypto from 0.23.0 to 0.24.0
2 weeks ago
Max d5171be998
Merge branch 'master' into dependabot/go_modules/golang.org/x/crypto-0.24.0 2 weeks ago
github-actions[bot] 6e12cfa46c
Merge pull request #1880 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.47.0
Bump go.step.sm/crypto from 0.46.0 to 0.47.0
2 weeks ago
Max d1de1ad8df
Merge branch 'master' into dependabot/go_modules/google.golang.org/api-0.183.0 2 weeks ago
Max 0ce8fb6db5
Merge branch 'master' into dependabot/go_modules/golang.org/x/crypto-0.24.0 2 weeks ago
Max 3b9631b883
Merge branch 'master' into dependabot/go_modules/go.step.sm/crypto-0.47.0 2 weeks ago
Max 474f5d28f4
Update hardcoded AWS certs (#1881) 2 weeks ago
dependabot[bot] 7ab8391070
Bump go.step.sm/crypto from 0.46.0 to 0.47.0
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.46.0 to 0.47.0.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.46.0...v0.47.0)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 weeks ago
dependabot[bot] 23f120e9db
Bump golang.org/x/crypto from 0.23.0 to 0.24.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.23.0 to 0.24.0.
- [Commits](https://github.com/golang/crypto/compare/v0.23.0...v0.24.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 weeks ago
dependabot[bot] e3444c0736
Bump google.golang.org/api from 0.182.0 to 0.183.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.182.0 to 0.183.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.182.0...v0.183.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 weeks ago
github-actions[bot] 669d992d59
Merge pull request #1870 from smallstep/dependabot/go_modules/google.golang.org/api-0.182.0
Bump google.golang.org/api from 0.181.0 to 0.182.0
3 weeks ago
github-actions[bot] 68c5238fe7
Merge pull request #1869 from smallstep/dependabot/go_modules/github.com/hashicorp/vault/api/auth/approle-0.7.0
Bump github.com/hashicorp/vault/api/auth/approle from 0.6.0 to 0.7.0
3 weeks ago
github-actions[bot] 4884379710
Merge pull request #1868 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.46.0
Bump go.step.sm/crypto from 0.45.1 to 0.46.0
3 weeks ago
dependabot[bot] 437154d70e
Bump google.golang.org/api from 0.181.0 to 0.182.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.181.0 to 0.182.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.181.0...v0.182.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
3 weeks ago
dependabot[bot] 2a9bbff8ce
Bump github.com/hashicorp/vault/api/auth/approle from 0.6.0 to 0.7.0
Bumps [github.com/hashicorp/vault/api/auth/approle](https://github.com/hashicorp/vault) from 0.6.0 to 0.7.0.
- [Release notes](https://github.com/hashicorp/vault/releases)
- [Changelog](https://github.com/hashicorp/vault/blob/main/CHANGELOG-v0.md)
- [Commits](https://github.com/hashicorp/vault/compare/v0.6.0...v0.7.0)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/vault/api/auth/approle
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
3 weeks ago
dependabot[bot] 4d7ca9d672
Bump go.step.sm/crypto from 0.45.1 to 0.46.0
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.45.1 to 0.46.0.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.45.1...v0.46.0)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
3 weeks ago
github-actions[bot] 587d0d5a27
Merge pull request #1858 from smallstep/dependabot/go_modules/cloud.google.com/go/security-1.17.0
Bump cloud.google.com/go/security from 1.16.1 to 1.17.0
4 weeks ago
dependabot[bot] 34fde59927
Bump cloud.google.com/go/security from 1.16.1 to 1.17.0
Bumps [cloud.google.com/go/security](https://github.com/googleapis/google-cloud-go) from 1.16.1 to 1.17.0.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/documentai/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/video/v1.16.1...kms/v1.17.0)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/security
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
4 weeks ago
github-actions[bot] fe8c3d3ee8
Merge pull request #1859 from smallstep/dependabot/go_modules/github.com/hashicorp/vault/api/auth/kubernetes-0.7.0
Bump github.com/hashicorp/vault/api/auth/kubernetes from 0.6.0 to 0.7.0
4 weeks ago
dependabot[bot] 013c2f2f04
Bump github.com/hashicorp/vault/api/auth/kubernetes from 0.6.0 to 0.7.0
Bumps [github.com/hashicorp/vault/api/auth/kubernetes](https://github.com/hashicorp/vault) from 0.6.0 to 0.7.0.
- [Release notes](https://github.com/hashicorp/vault/releases)
- [Changelog](https://github.com/hashicorp/vault/blob/main/CHANGELOG-v0.md)
- [Commits](https://github.com/hashicorp/vault/compare/v0.6.0...v0.7.0)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/vault/api/auth/kubernetes
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
4 weeks ago
github-actions[bot] 4208b0a63f
Merge pull request #1860 from smallstep/dependabot/go_modules/github.com/hashicorp/vault/api-1.14.0
Bump github.com/hashicorp/vault/api from 1.13.0 to 1.14.0
4 weeks ago
github-actions[bot] 6de7aa97dc
Merge pull request #1861 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.45.1
Bump go.step.sm/crypto from 0.45.0 to 0.45.1
4 weeks ago
dependabot[bot] f3e4f0ae64
Bump go.step.sm/crypto from 0.45.0 to 0.45.1
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.45.0 to 0.45.1.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.45.0...v0.45.1)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
4 weeks ago
dependabot[bot] 2b8f3e7080
Bump github.com/hashicorp/vault/api from 1.13.0 to 1.14.0
Bumps [github.com/hashicorp/vault/api](https://github.com/hashicorp/vault) from 1.13.0 to 1.14.0.
- [Release notes](https://github.com/hashicorp/vault/releases)
- [Changelog](https://github.com/hashicorp/vault/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/vault/compare/v1.13.0...v1.14.0)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/vault/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
4 weeks ago
Mariano Cano 47b5048d82
Merge pull request #1850 from smallstep/mariano/signer
Add GetX509Signer method
1 month ago
github-actions[bot] 7d6eea0ff0
Merge pull request #1853 from smallstep/dependabot/go_modules/google.golang.org/grpc-1.64.0
Bump google.golang.org/grpc from 1.63.2 to 1.64.0
1 month ago
max furman 99ce13a4ea
Fix linter warnings 1 month ago
dependabot[bot] 5cdfc2c972
Bump google.golang.org/grpc from 1.63.2 to 1.64.0
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.63.2 to 1.64.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.63.2...v1.64.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 month ago
github-actions[bot] 980687bc0e
Merge pull request #1854 from smallstep/dependabot/go_modules/google.golang.org/api-0.181.0
Bump google.golang.org/api from 0.180.0 to 0.181.0
1 month ago
dependabot[bot] 8121a05c55
Bump google.golang.org/api from 0.180.0 to 0.181.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.180.0 to 0.181.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.180.0...v0.181.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 month ago
Mariano Cano ad0ac55b41
Merge pull request #1844 from smallstep/mariano/account-provisioner
Verify provisioner with id if available
1 month ago
Mariano Cano 192e90eea7
Merge branch 'master' into mariano/account-provisioner 1 month ago
Mariano Cano 812ffd3c40
Reverse assert statements 1 month ago
Mariano Cano d0548f9ec9
Use %q instead of '%s'
Co-authored-by: Herman Slatman <hslatman@users.noreply.github.com>
1 month ago
Mariano Cano 14959dbb2e
Merge pull request #1849 from smallstep/mariano/log-errors
Log errors using slog.Logger
1 month ago
Mariano Cano c0b7c33a58
Use a function as the error logger
This commit addresses comment in the code review. Now, instead of
injecting an slog.Logger we can inject any method that can use a more
flexible implementation.
1 month ago
Mariano Cano 9e8087fbb1
Add GetX509Signer method
This commit adds a method to the Authority type that returns the signer
used to sign X509 certificates.
1 month ago
Mariano Cano 8673818980
Split provisioner check in two cases 1 month ago
Mariano Cano f3f484cee2
Log errors using slog.Logger
This commit allows logging errors in a slog.Logger injected in the
context. This type of logger is not currently used directly in step-ca,
but this will change in the future.
1 month ago
Mariano Cano fdb0cf03f6
Merge pull request #1848 from smallstep/mariano/intermediates
Add methods to get the intermediate certificates
1 month ago
Mariano Cano d4862a2520
Add methods to get the intermediate certificates
This commit adds new methods to get the intermediate certificates.
1 month ago
Mariano Cano e08b27708b
Merge pull request #1847 from smallstep/mariano/x5c-insecure
Upgrade go.step.sm/crypto to v0.45.0
1 month ago
Mariano Cano b6afed3be7
Upgrade go.step.sm/crypto to v0.45.0
This commit upgrades go.step.sm/crypto to a version that fixes
`jose.ParseX5cInsecure`. It should require a certificate with ClientAuth
instead of the default ServerAuth.
1 month ago
github-actions[bot] 9355923799
Merge pull request #1839 from smallstep/dependabot/go_modules/google.golang.org/api-0.180.0
Bump google.golang.org/api from 0.177.0 to 0.180.0
1 month ago
dependabot[bot] a8e9a18bcc
Bump google.golang.org/api from 0.177.0 to 0.180.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.177.0 to 0.180.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.177.0...v0.180.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 month ago
github-actions[bot] 803d3d3981
Merge pull request #1840 from smallstep/dependabot/go_modules/google.golang.org/protobuf-1.34.1
Bump google.golang.org/protobuf from 1.34.0 to 1.34.1
1 month ago
github-actions[bot] e0e7ae6c89
Merge pull request #1841 from smallstep/dependabot/go_modules/golang.org/x/net-0.25.0
Bump golang.org/x/net from 0.24.0 to 0.25.0
1 month ago
github-actions[bot] 72a8bb3d39
Merge pull request #1842 from smallstep/dependabot/go_modules/github.com/prometheus/client_golang-1.19.1
Bump github.com/prometheus/client_golang from 1.19.0 to 1.19.1
1 month ago
Mariano Cano 5fa5a63de8
Verify provisioner with id if available
This commit allows verifying the account provisioner with the request
provisioner using the ID instead of the name. When the provisioner are
stored in the DB, the provisioner ID is not mutable but the name is.
1 month ago
dependabot[bot] 9cbdc73809
Bump github.com/prometheus/client_golang from 1.19.0 to 1.19.1
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.19.0 to 1.19.1.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.19.0...v1.19.1)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 month ago
dependabot[bot] 42341c7a39
Bump golang.org/x/net from 0.24.0 to 0.25.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.24.0 to 0.25.0.
- [Commits](https://github.com/golang/net/compare/v0.24.0...v0.25.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 month ago
dependabot[bot] 0dff5c4b84
Bump google.golang.org/protobuf from 1.34.0 to 1.34.1
Bumps google.golang.org/protobuf from 1.34.0 to 1.34.1.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 month ago
github-actions[bot] e3ba702811
Merge pull request #1827 from smallstep/dependabot/go_modules/golang.org/x/crypto-0.23.0
Bump golang.org/x/crypto from 0.22.0 to 0.23.0
2 months ago
github-actions[bot] fe29ccaee3
Merge pull request #1828 from smallstep/dependabot/go_modules/github.com/newrelic/go-agent/v3-3.33.0
Bump github.com/newrelic/go-agent/v3 from 3.32.0 to 3.33.0
2 months ago
github-actions[bot] 8cf5e3c2c6
Merge pull request #1829 from smallstep/dependabot/go_modules/cloud.google.com/go/longrunning-0.5.7
Bump cloud.google.com/go/longrunning from 0.5.6 to 0.5.7
2 months ago
dependabot[bot] 928d446e93
Bump golang.org/x/crypto from 0.22.0 to 0.23.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.22.0 to 0.23.0.
- [Commits](https://github.com/golang/crypto/compare/v0.22.0...v0.23.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 months ago
dependabot[bot] e11833ef7a
Bump cloud.google.com/go/longrunning from 0.5.6 to 0.5.7
Bumps [cloud.google.com/go/longrunning](https://github.com/googleapis/google-cloud-go) from 0.5.6 to 0.5.7.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/longrunning/v0.5.6...longrunning/v0.5.7)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/longrunning
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2 months ago
github-actions[bot] 591b9f743d
Merge pull request #1826 from smallstep/dependabot/go_modules/cloud.google.com/go/security-1.16.1
Bump cloud.google.com/go/security from 1.16.0 to 1.16.1
2 months ago
Mariano Cano a2f2332848
Merge pull request #1831 from smallstep/mariano/err-not-found
Use always acme.IsErrNotFound
2 months ago
Mariano Cano b1e31b1726
Use always acme.IsErrNotFound
This commit replaces the comparisons with acme.ErrNotFound and always
uses acme.IsErrNotFound.
2 months ago
Mariano Cano cca6f6d01b
Merge pull request #1830 from smallstep/mariano/provisioner-id
Add provisioner id to acme accounts
2 months ago
Mariano Cano d037ed6ff2
Add provisioner id to acme accounts
This commit adds a new field that allows to have a reference to
a provisioner id in the acme account.
2 months ago
dependabot[bot] 9b2566556e
Bump github.com/newrelic/go-agent/v3 from 3.32.0 to 3.33.0
Bumps [github.com/newrelic/go-agent/v3](https://github.com/newrelic/go-agent) from 3.32.0 to 3.33.0.
- [Release notes](https://github.com/newrelic/go-agent/releases)
- [Changelog](https://github.com/newrelic/go-agent/blob/master/CHANGELOG.md)
- [Commits](https://github.com/newrelic/go-agent/compare/v3.32.0...v3.33.0)

---
updated-dependencies:
- dependency-name: github.com/newrelic/go-agent/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 months ago
dependabot[bot] 8933a2e514
Bump cloud.google.com/go/security from 1.16.0 to 1.16.1
Bumps [cloud.google.com/go/security](https://github.com/googleapis/google-cloud-go) from 1.16.0 to 1.16.1.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/documentai/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/video/v1.16.0...video/v1.16.1)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/security
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2 months ago
github-actions[bot] 2c71543d33
Merge pull request #1817 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.44.8
Bump go.step.sm/crypto from 0.44.6 to 0.44.8
2 months ago
Herman Slatman 949e2fdb1c
Fix test error expectation in `TestAuthorityNew` 2 months ago
dependabot[bot] 281efbb949
Bump go.step.sm/crypto from 0.44.6 to 0.44.8
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.44.6 to 0.44.8.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.44.6...v0.44.8)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2 months ago
github-actions[bot] 14b1211e7a
Merge pull request #1815 from smallstep/dependabot/go_modules/github.com/urfave/cli-1.22.15
Bump github.com/urfave/cli from 1.22.14 to 1.22.15
2 months ago
github-actions[bot] 0b894a0d4a
Merge pull request #1816 from smallstep/dependabot/go_modules/google.golang.org/api-0.176.1
Bump google.golang.org/api from 0.176.0 to 0.176.1
2 months ago
Mariano Cano 20e315bac0
Merge pull request #1819 from smallstep/mariano/not-found
Make IsErrNotFound more flexible
2 months ago
Mariano Cano 296ac4e207
Make ISErrNotFound more flexible
This commit allows to use the standard error sql.ErrNoRows for not found
errors.
2 months ago
github-actions[bot] 28a87bbaa6
Merge pull request #1818 from smallstep/dependabot/github_actions/dependabot/fetch-metadata-2.1.0
Bump dependabot/fetch-metadata from 2.0.0 to 2.1.0
2 months ago
dependabot[bot] bf03d56ae4
Bump dependabot/fetch-metadata from 2.0.0 to 2.1.0
Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 2.0.0 to 2.1.0.
- [Release notes](https://github.com/dependabot/fetch-metadata/releases)
- [Commits](https://github.com/dependabot/fetch-metadata/compare/v2.0.0...v2.1.0)

---
updated-dependencies:
- dependency-name: dependabot/fetch-metadata
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 months ago
dependabot[bot] 6715c653ca
Bump google.golang.org/api from 0.176.0 to 0.176.1
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.176.0 to 0.176.1.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.176.0...v0.176.1)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2 months ago
dependabot[bot] 798e190621
Bump github.com/urfave/cli from 1.22.14 to 1.22.15
Bumps [github.com/urfave/cli](https://github.com/urfave/cli) from 1.22.14 to 1.22.15.
- [Release notes](https://github.com/urfave/cli/releases)
- [Changelog](https://github.com/urfave/cli/blob/main/docs/CHANGELOG.md)
- [Commits](https://github.com/urfave/cli/compare/v1.22.14...v1.22.15)

---
updated-dependencies:
- dependency-name: github.com/urfave/cli
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2 months ago
findnature 5072d7a58f
chore: fix function names in comment (#1813)
Signed-off-by: findnature <cricis@aliyun.com>
2 months ago
Max 9cbab5a5b3
Add changelog for 0.26.1 (#1812) 2 months ago
Jeremy Doupe 03c3cf5790 fixed Scopes and AuthParams assignment 2 months ago
Herman Slatman d6bf551f87
Merge pull request #1803 from smallstep/herman/fix-scep-vault-ra
Fix CA startup with Vault RA configuration
2 months ago
github-actions[bot] f4d506f659
Merge pull request #1811 from smallstep/dependabot/go_modules/github.com/hashicorp/vault/api-1.13.0
Bump github.com/hashicorp/vault/api from 1.12.2 to 1.13.0
2 months ago
Herman Slatman 1e5e267b2b
Remove leftover debug print 2 months ago
max furman 760014c64b
go mod tidy 2 months ago
Herman Slatman 2561a7271e
Dedupe CA and SCEP client creation logic 2 months ago
dependabot[bot] 39653050dc
Bump github.com/hashicorp/vault/api from 1.12.2 to 1.13.0
Bumps [github.com/hashicorp/vault/api](https://github.com/hashicorp/vault) from 1.12.2 to 1.13.0.
- [Release notes](https://github.com/hashicorp/vault/releases)
- [Changelog](https://github.com/hashicorp/vault/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/vault/compare/v1.12.2...v1.13.0)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/vault/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 months ago
github-actions[bot] 65cfee56df
Merge pull request #1810 from smallstep/dependabot/go_modules/google.golang.org/api-0.176.0
Bump google.golang.org/api from 0.172.0 to 0.176.0
2 months ago
dependabot[bot] 8d4effcce8
Bump google.golang.org/api from 0.172.0 to 0.176.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.172.0 to 0.176.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.172.0...v0.176.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 months ago
github-actions[bot] 4a375592d3
Merge pull request #1809 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.44.6
Bump go.step.sm/crypto from 0.44.4 to 0.44.6
2 months ago
github-actions[bot] d7ed03124f
Merge pull request #1808 from smallstep/dependabot/go_modules/cloud.google.com/go/security-1.16.0
Bump cloud.google.com/go/security from 1.15.6 to 1.16.0
2 months ago
Herman Slatman 87202001a8
Rewrite SCEP integration tests to only use the HTTPS endpoint 2 months ago
dependabot[bot] 57a6b85388
Bump go.step.sm/crypto from 0.44.4 to 0.44.6
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.44.4 to 0.44.6.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.44.4...v0.44.6)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2 months ago
dependabot[bot] 0ba61c58e8
Bump cloud.google.com/go/security from 1.15.6 to 1.16.0
Bumps [cloud.google.com/go/security](https://github.com/googleapis/google-cloud-go) from 1.15.6 to 1.16.0.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/documentai/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/kms/v1.15.6...asset/v1.16.0)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/security
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 months ago
Herman Slatman b0fabe1346
Add some SCEP integration tests 2 months ago
Herman Slatman 113a6dd8ab
Remove reporting the CA mode from startup logs 2 months ago
Herman Slatman 6bc0a86207
Fix CA startup with Vault RA configuration 2 months ago
Jeremy Doupe aa543a335a
add Scopes to OIDC struct 2 months ago
Jeremy Doupe 4879376138
add AuthParams and Scopes to linkedca OIDC structures 2 months ago
Jeremy Doupe 2fcf34066b
add AuthParams to OIDC struct 2 months ago
Herman Slatman 07279dd248
Merge pull request #1801 from smallstep/herman/upgrade-crypto-v0.44.4
Upgrade `go.step.sm/crypto` to `v0.44.4`
2 months ago
Herman Slatman 4c6b0b318e
Upgrade `go.step.sm/crypto` to `v0.44.4` 2 months ago
Herman Slatman f1a2c68f43
Merge pull request #1798 from smallstep/herman/fix-instrumented-key-manager
Add support for `kmsapi.Decrypter` to instrumented key manager
2 months ago
Mariano Cano 7df3ad05ed
Merge pull request #1797 from smallstep/mariano/init-scep
Allow custom SCEP key manager
3 months ago
Mariano Cano 4202d6673c
Remove debug statement 3 months ago
Herman Slatman d6bbe5b06b
Add support for `kmsapi.Decrypter` to instrumented key manager 3 months ago
Herman Slatman 721345eea6
Merge pull request #1793 from verytrap/master
chore: fix function names in comment
3 months ago
verytrap db92404342 chore: fix function names in comment
Signed-off-by: verytrap <wangqiuyue@outlook.com>
3 months ago
Mariano Cano 725a913f66
Allow custom SCEP key manager
This commit allows to inject a custom key manger for SCEP.
3 months ago
Herman Slatman 397877a7b6
Merge pull request #1795 from smallstep/herman/fix-scep-failinfo-oid
Prevent exposing any internal details in SCEP failure message
3 months ago
Herman Slatman b226b6eb4c
Prevent exposing any internal details in SCEP failure message
To be on the safe side, block errors from signing operations from
being returned to the client. We should revisit, and make it return
a more informative error, but with high assurance that no sensitive
information is added to the message.
3 months ago
Herman Slatman 02956ad0e3
Merge pull request #1794 from smallstep/herman/fix-scep-failinfo-oid
Fix the `id-scep-failInfoText` OID
3 months ago
Herman Slatman 037554e774
Fix the `id-scep-failInfoText` OID 3 months ago
github-actions[bot] 1513152cb2
Merge pull request #1791 from smallstep/dependabot/go_modules/github.com/newrelic/go-agent/v3-3.32.0
Bump github.com/newrelic/go-agent/v3 from 3.31.0 to 3.32.0
3 months ago
dependabot[bot] c9ba31ae61
Bump github.com/newrelic/go-agent/v3 from 3.31.0 to 3.32.0
Bumps [github.com/newrelic/go-agent/v3](https://github.com/newrelic/go-agent) from 3.31.0 to 3.32.0.
- [Release notes](https://github.com/newrelic/go-agent/releases)
- [Changelog](https://github.com/newrelic/go-agent/blob/master/CHANGELOG.md)
- [Commits](https://github.com/newrelic/go-agent/compare/v3.31.0...v3.32.0)

---
updated-dependencies:
- dependency-name: github.com/newrelic/go-agent/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
3 months ago
github-actions[bot] 1f69ff84a1
Merge pull request #1792 from smallstep/dependabot/go_modules/google.golang.org/grpc-1.63.2
Bump google.golang.org/grpc from 1.62.1 to 1.63.2
3 months ago
dependabot[bot] a76f07143b
Bump google.golang.org/grpc from 1.62.1 to 1.63.2
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.62.1 to 1.63.2.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.62.1...v1.63.2)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
3 months ago
github-actions[bot] 08ef9fe245
Merge pull request #1789 from smallstep/dependabot/go_modules/golang.org/x/net-0.24.0
Bump golang.org/x/net from 0.22.0 to 0.24.0
3 months ago
dependabot[bot] 57d628513b
Bump golang.org/x/net from 0.22.0 to 0.24.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.22.0 to 0.24.0.
- [Commits](https://github.com/golang/net/compare/v0.22.0...v0.24.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
3 months ago
github-actions[bot] d5758ba3a3
Merge pull request #1784 from smallstep/dependabot/go_modules/github.com/newrelic/go-agent/v3-3.31.0
Bump github.com/newrelic/go-agent/v3 from 3.30.0 to 3.31.0
3 months ago
github-actions[bot] 166c4968cf
Merge pull request #1785 from smallstep/dependabot/go_modules/google.golang.org/api-0.172.0
Bump google.golang.org/api from 0.171.0 to 0.172.0
3 months ago
Carl Tashian 1be0932a0f
Merge pull request #1786 from smallstep/carl/winget-fix
Fix winget release notes URL
3 months ago
Carl Tashian f04a5e39c4
Fix winget release URL 3 months ago
dependabot[bot] d1523c93bc
Bump google.golang.org/api from 0.171.0 to 0.172.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.171.0 to 0.172.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.171.0...v0.172.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
3 months ago
dependabot[bot] 44c48a7494
Bump github.com/newrelic/go-agent/v3 from 3.30.0 to 3.31.0
Bumps [github.com/newrelic/go-agent/v3](https://github.com/newrelic/go-agent) from 3.30.0 to 3.31.0.
- [Release notes](https://github.com/newrelic/go-agent/releases)
- [Changelog](https://github.com/newrelic/go-agent/blob/master/CHANGELOG.md)
- [Commits](https://github.com/newrelic/go-agent/compare/v3.30.0...v3.31.0)

---
updated-dependencies:
- dependency-name: github.com/newrelic/go-agent/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
3 months ago
Carl Tashian 188e4e3ff3
Add version number to winget branch name (#1783) 3 months ago
Max 395a3eeb93
Update go.step.sm/crypto (#1781) 3 months ago
Herman Slatman 4772d7cc28
Merge pull request #1780 from smallstep/herman/update-changelog-20240328
Update changelog for `v0.26.0` release
3 months ago
Herman Slatman 854288a0cb
Update changelog for `v0.26.0` release 3 months ago
github-actions[bot] 4016b69b28
Merge pull request #1776 from smallstep/dependabot/go_modules/github.com/hashicorp/vault/api-1.12.2
Bump github.com/hashicorp/vault/api from 1.12.1 to 1.12.2
3 months ago
github-actions[bot] b5b723e835
Merge pull request #1775 from smallstep/dependabot/go_modules/google.golang.org/api-0.171.0
Bump google.golang.org/api from 0.169.0 to 0.171.0
3 months ago
github-actions[bot] 0a6e79a745
Merge pull request #1778 from smallstep/dependabot/github_actions/dependabot/fetch-metadata-2.0.0
Bump dependabot/fetch-metadata from 1.6.0 to 2.0.0
3 months ago
dependabot[bot] 9d86361ae3
Bump github.com/hashicorp/vault/api from 1.12.1 to 1.12.2
Bumps [github.com/hashicorp/vault/api](https://github.com/hashicorp/vault) from 1.12.1 to 1.12.2.
- [Release notes](https://github.com/hashicorp/vault/releases)
- [Changelog](https://github.com/hashicorp/vault/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/vault/compare/v1.12.1...v1.12.2)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/vault/api
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
3 months ago
github-actions[bot] 7e053437b1
Merge pull request #1774 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.44.1
Bump go.step.sm/crypto from 0.43.1 to 0.44.1
3 months ago
dependabot[bot] 014b4ef2c0
Bump dependabot/fetch-metadata from 1.6.0 to 2.0.0
Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 1.6.0 to 2.0.0.
- [Release notes](https://github.com/dependabot/fetch-metadata/releases)
- [Commits](https://github.com/dependabot/fetch-metadata/compare/v1.6.0...v2.0.0)

---
updated-dependencies:
- dependency-name: dependabot/fetch-metadata
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
3 months ago
dependabot[bot] 21734f7742
Bump google.golang.org/api from 0.169.0 to 0.171.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.169.0 to 0.171.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.169.0...v0.171.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
3 months ago
dependabot[bot] 927cd97bd5
Bump go.step.sm/crypto from 0.43.1 to 0.44.1
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.43.1 to 0.44.1.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.43.1...v0.44.1)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
3 months ago
Herman Slatman 2650944d65
Merge pull request #1773 from smallstep/herman/cosign-2.x
Use `--yes` to acknowledge user prompts for `cosign` signing
3 months ago
Herman Slatman 7888d868ba
Use `--yes` to acknowledge user prompts for `cosign` signing 3 months ago
Joe Doss 56c4f3bdd5
Merge pull request #1772 from smallstep/jdoss/Enable_tpmkms
Enable tpmkms
3 months ago
Joe Doss 14c9de2570
Enable tpmkms. 3 months ago
github-actions[bot] 44f44e34e4
Merge pull request #1767 from smallstep/dependabot/go_modules/cloud.google.com/go/longrunning-0.5.6
Bump cloud.google.com/go/longrunning from 0.5.5 to 0.5.6
3 months ago
github-actions[bot] 73c827c7fa
Merge pull request #1768 from smallstep/dependabot/go_modules/github.com/hashicorp/vault/api-1.12.1
Bump github.com/hashicorp/vault/api from 1.12.0 to 1.12.1
3 months ago
dependabot[bot] 9874214669
Bump cloud.google.com/go/longrunning from 0.5.5 to 0.5.6
Bumps [cloud.google.com/go/longrunning](https://github.com/googleapis/google-cloud-go) from 0.5.5 to 0.5.6.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/longrunning/v0.5.5...longrunning/v0.5.6)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/longrunning
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
3 months ago
github-actions[bot] c5a13d86ba
Merge pull request #1766 from smallstep/dependabot/go_modules/golang.org/x/net-0.22.0
Bump golang.org/x/net from 0.21.0 to 0.22.0
3 months ago
github-actions[bot] 70085fcfeb
Merge pull request #1769 from smallstep/dependabot/go_modules/cloud.google.com/go/security-1.15.6
Bump cloud.google.com/go/security from 1.15.5 to 1.15.6
3 months ago
dependabot[bot] 1a768ad522
Bump cloud.google.com/go/security from 1.15.5 to 1.15.6
Bumps [cloud.google.com/go/security](https://github.com/googleapis/google-cloud-go) from 1.15.5 to 1.15.6.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/kms/v1.15.5...kms/v1.15.6)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/security
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
3 months ago
dependabot[bot] 4dfade10b8
Bump github.com/hashicorp/vault/api from 1.12.0 to 1.12.1
Bumps [github.com/hashicorp/vault/api](https://github.com/hashicorp/vault) from 1.12.0 to 1.12.1.
- [Release notes](https://github.com/hashicorp/vault/releases)
- [Changelog](https://github.com/hashicorp/vault/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/vault/compare/v1.12.0...v1.12.1)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/vault/api
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
3 months ago
dependabot[bot] 9a75f93250
Bump golang.org/x/net from 0.21.0 to 0.22.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.21.0 to 0.22.0.
- [Commits](https://github.com/golang/net/compare/v0.21.0...v0.22.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
3 months ago
Mariano Cano fe364d5081
Merge pull request #1764 from smallstep/mariano/ra-lifetime
Let the CA determine the RA lifetime
4 months ago
Mariano Cano 0ac9023590
Fix typo in error message and comment 4 months ago
Mariano Cano 10f6a901ec
Let the CA determine the RA lifetime
When the RA mode with StepCAS is used, let the CA decide which lifetime
the RA should get instead of requiring always 24h.

This commit also fixes linter warnings.

Related to #1094
4 months ago
Herman Slatman ef1631b00d
Merge pull request #1762 from smallstep/herman/upgrade-pgx-v4.18.3
Upgrade `pgx` to `v4.18.3`
4 months ago
Herman Slatman 6204a1441e
Upgrade `pgx` to `v4.18.3` 4 months ago
github-actions[bot] d03700b155
Merge pull request #1761 from smallstep/dependabot/go_modules/google.golang.org/grpc-1.62.1
Bump google.golang.org/grpc from 1.62.0 to 1.62.1
4 months ago
github-actions[bot] 1362d4dea6
Merge pull request #1759 from smallstep/dependabot/go_modules/go.step.sm/cli-utils-0.9.0
Bump go.step.sm/cli-utils from 0.8.0 to 0.9.0
4 months ago
dependabot[bot] cc7ac97c51
Bump go.step.sm/cli-utils from 0.8.0 to 0.9.0
Bumps [go.step.sm/cli-utils](https://github.com/smallstep/cli-utils) from 0.8.0 to 0.9.0.
- [Release notes](https://github.com/smallstep/cli-utils/releases)
- [Commits](https://github.com/smallstep/cli-utils/compare/v0.8.0...v0.9.0)

---
updated-dependencies:
- dependency-name: go.step.sm/cli-utils
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
4 months ago
dependabot[bot] 22781b8460
Bump google.golang.org/grpc from 1.62.0 to 1.62.1
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.62.0 to 1.62.1.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.62.0...v1.62.1)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
4 months ago
github-actions[bot] 9033120401
Merge pull request #1758 from smallstep/dependabot/go_modules/google.golang.org/api-0.169.0
Bump google.golang.org/api from 0.167.0 to 0.169.0
4 months ago
github-actions[bot] 87506d738c
Merge pull request #1760 from smallstep/dependabot/go_modules/golang.org/x/crypto-0.21.0
Bump golang.org/x/crypto from 0.19.0 to 0.21.0
4 months ago
dependabot[bot] 4940556234
Bump golang.org/x/crypto from 0.19.0 to 0.21.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.19.0 to 0.21.0.
- [Commits](https://github.com/golang/crypto/compare/v0.19.0...v0.21.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
4 months ago
dependabot[bot] 299102955b
Bump google.golang.org/api from 0.167.0 to 0.169.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.167.0 to 0.169.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.167.0...v0.169.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
4 months ago
Herman Slatman 5254702130
Merge pull request #1755 from smallstep/herman/export-requestid-middleware
Export `requestid` middleware
4 months ago
Herman Slatman b7a6b93717
Add package comment 4 months ago
github-actions[bot] 9b1dfcf5d0
Merge pull request #1756 from smallstep/dependabot/go_modules/github.com/go-jose/go-jose/v3-3.0.3
Bump github.com/go-jose/go-jose/v3 from 3.0.2 to 3.0.3
4 months ago
dependabot[bot] 9327859f55
Bump github.com/go-jose/go-jose/v3 from 3.0.2 to 3.0.3
Bumps [github.com/go-jose/go-jose/v3](https://github.com/go-jose/go-jose) from 3.0.2 to 3.0.3.
- [Release notes](https://github.com/go-jose/go-jose/releases)
- [Changelog](https://github.com/go-jose/go-jose/blob/v3.0.3/CHANGELOG.md)
- [Commits](https://github.com/go-jose/go-jose/compare/v3.0.2...v3.0.3)

---
updated-dependencies:
- dependency-name: github.com/go-jose/go-jose/v3
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
4 months ago
Carl Tashian 26b7761a9c
Merge pull request #1719 from smallstep/carl/fix-ra-install
Update RA installer step-ca package URL
4 months ago
Herman Slatman b8510dd5b2
Make the `requestid` an exported middleware 4 months ago
Herman Slatman 4cae19f94f
Merge pull request #1753 from smallstep/fix-peak-typo
Fix `peak` -> `peek`
4 months ago
Herman Slatman af76ebdc1d
Fix `peak` -> `peek` 4 months ago
github-actions[bot] 2e9c5bbc1a
Merge pull request #1747 from smallstep/dependabot/go_modules/github.com/go-chi/chi/v5-5.0.12
Bump github.com/go-chi/chi/v5 from 5.0.11 to 5.0.12
4 months ago
Herman Slatman a7a4b47ead
Merge pull request #1751 from smallstep/herman/handle-server-startup-errors
Handle CA server startup errors
4 months ago
Herman Slatman 01de10d447
Merge pull request #1752 from smallstep/herman/upgrade-protobuf-v1.33.0
Upgrade `google.golang.org/protobuf` to `v1.33.0`
4 months ago
Herman Slatman fa5117adaa
Upgrade `google.golang.org/protobuf` to `v1.33.0` 4 months ago
Herman Slatman bbb80cde16
Add startup error shutdown message to log 4 months ago
Herman Slatman f02d4546a9
Handle CA server startup errors 4 months ago
github-actions[bot] ec223c1cc2
Merge pull request #1748 from smallstep/dependabot/go_modules/github.com/stretchr/testify-1.9.0
Bump github.com/stretchr/testify from 1.8.4 to 1.9.0
4 months ago
github-actions[bot] b7e3e0be20
Merge pull request #1746 from smallstep/dependabot/go_modules/google.golang.org/api-0.167.0
Bump google.golang.org/api from 0.165.0 to 0.167.0
4 months ago
github-actions[bot] 022deaf610
Merge pull request #1749 from smallstep/dependabot/go_modules/github.com/prometheus/client_golang-1.19.0
Bump github.com/prometheus/client_golang from 1.18.0 to 1.19.0
4 months ago
dependabot[bot] 5853c73268
Bump github.com/prometheus/client_golang from 1.18.0 to 1.19.0
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.18.0 to 1.19.0.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.18.0...v1.19.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
4 months ago
dependabot[bot] cf0d6f8f5c
Bump github.com/stretchr/testify from 1.8.4 to 1.9.0
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.4 to 1.9.0.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.8.4...v1.9.0)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
4 months ago
dependabot[bot] 3656b458ea
Bump github.com/go-chi/chi/v5 from 5.0.11 to 5.0.12
Bumps [github.com/go-chi/chi/v5](https://github.com/go-chi/chi) from 5.0.11 to 5.0.12.
- [Release notes](https://github.com/go-chi/chi/releases)
- [Changelog](https://github.com/go-chi/chi/blob/master/CHANGELOG.md)
- [Commits](https://github.com/go-chi/chi/compare/v5.0.11...v5.0.12)

---
updated-dependencies:
- dependency-name: github.com/go-chi/chi/v5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
4 months ago
dependabot[bot] 69c7ca9809
Bump google.golang.org/api from 0.165.0 to 0.167.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.165.0 to 0.167.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.165.0...v0.167.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
4 months ago
Herman Slatman 10aa48c74a
Merge pull request #1743 from smallstep/herman/improve-request-id
Improve end-to-end request ID propagation
4 months ago
Herman Slatman 2a47644d31
Fix linting issue 4 months ago
Herman Slatman d392c169fc
Improve functional coverage of request ID integration test 4 months ago
Herman Slatman 7fd524f70b
Default to generating request IDs using UUIDv4 format in CA 4 months ago
Herman Slatman 0898c6db97
Use UUIDv4 as automatically generated client request identifier 4 months ago
Carl Tashian 0d5c692b2c
Merge pull request #1744 from smallstep/carl/readme-updates
Updated README
4 months ago
Carl Tashian cd3e91b198
Updated README 4 months ago
Herman Slatman b9d6bfc1eb
Cleanup CA client tests by removing `smallstep/assert` 4 months ago
Herman Slatman 532b9df0a3
Improve CA client request ID handling 4 months ago
Herman Slatman 06696e6492
Move user ID handling to `userid` package 4 months ago
Herman Slatman 7e5f10927f
Decouple request ID middleware from logging middleware 4 months ago
Herman Slatman 535e2a96d5
Fix the e2e request ID test (again) 4 months ago
Herman Slatman b83b8aa079
Make random TCP address reservation more contained 4 months ago
Herman Slatman 2255857b3a
Fix `client` shadowing and e2e request ID test case 4 months ago
Herman Slatman 5c2572c443
Add support for user provider `X-Request-Id` header value 4 months ago
Herman Slatman cf8a50157f
Add a basic e2e test for `X-Request-Id` reflection 4 months ago
Panagiotis Siatras fb4cd6fe81
fix: Webhook-related instruments
* fix: also instrument webhooks that do not reach the wire
* fix: register the webhook instrumentation
4 months ago
Herman Slatman a58f5956e3
Add reflection of request ID in `X-Request-Id` response header 4 months ago
Herman Slatman c798735f7e
Merge pull request #1542 from smallstep/herman/webhook-request-id
Propagate request ID when webhook requests are made
4 months ago
Herman Slatman c1c2e73475
Add `X-Request-Id` to all requests made by our CA clients 4 months ago
Herman Slatman 4213a190d5
Use `X-Request-Id` as canonical request identifier (if available)
If `X-Request-Id` is available in an HTTP request made against the
CA server, it'll be used as the identifier for the request. This
slightly changes the existing behavior, which relied on the custom
`X-Smallstep-Id` header, but usage of that header is currently not
very widespread, and `X-Request-Id` is more generally known for
the use case `X-Smallstep-Id` is used for.

`X-Smallstep-Id` is currently still considered, but it'll only be
used if `X-Request-Id` is not set.
4 months ago
Herman Slatman 041b486c55
Remove usages of `Sign` without context 4 months ago
Herman Slatman c16a0b70ee
Remove `smallstep/assert` and `pkg/errors` from webhook tests 4 months ago
Herman Slatman 9689508709
Add tests for webhook request IDs 4 months ago
Herman Slatman 2a8b80a3e1
Merge branch 'master' into herman/webhook-request-id 4 months ago
github-actions[bot] 6ce502c50e
Merge pull request #1741 from smallstep/dependabot/go_modules/github.com/go-jose/go-jose/v3-3.0.2
Bump github.com/go-jose/go-jose/v3 from 3.0.1 to 3.0.2
4 months ago
github-actions[bot] 0d2aeff95c
Merge pull request #1739 from smallstep/dependabot/go_modules/google.golang.org/grpc-1.62.0
Bump google.golang.org/grpc from 1.61.0 to 1.62.0
4 months ago
dependabot[bot] 5ee2e0274c
Bump github.com/go-jose/go-jose/v3 from 3.0.1 to 3.0.2
Bumps [github.com/go-jose/go-jose/v3](https://github.com/go-jose/go-jose) from 3.0.1 to 3.0.2.
- [Release notes](https://github.com/go-jose/go-jose/releases)
- [Changelog](https://github.com/go-jose/go-jose/blob/main/CHANGELOG.md)
- [Commits](https://github.com/go-jose/go-jose/compare/v3.0.1...v3.0.2)

---
updated-dependencies:
- dependency-name: github.com/go-jose/go-jose/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
4 months ago
dependabot[bot] e4bbe8970e
Bump google.golang.org/grpc from 1.61.0 to 1.62.0
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.61.0 to 1.62.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.61.0...v1.62.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
4 months ago
github-actions[bot] 98a976b59e
Merge pull request #1740 from smallstep/dependabot/go_modules/github.com/fxamacker/cbor/v2-2.6.0
Bump github.com/fxamacker/cbor/v2 from 2.5.0 to 2.6.0
4 months ago
github-actions[bot] a583b59e1d
Merge pull request #1738 from smallstep/dependabot/go_modules/github.com/googleapis/gax-go/v2-2.12.2
Bump github.com/googleapis/gax-go/v2 from 2.12.0 to 2.12.2
4 months ago
dependabot[bot] 0b196b0b81
Bump github.com/fxamacker/cbor/v2 from 2.5.0 to 2.6.0
Bumps [github.com/fxamacker/cbor/v2](https://github.com/fxamacker/cbor) from 2.5.0 to 2.6.0.
- [Release notes](https://github.com/fxamacker/cbor/releases)
- [Commits](https://github.com/fxamacker/cbor/compare/v2.5.0...v2.6.0)

---
updated-dependencies:
- dependency-name: github.com/fxamacker/cbor/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
4 months ago
dependabot[bot] fa941dc967
Bump github.com/googleapis/gax-go/v2 from 2.12.0 to 2.12.2
Bumps [github.com/googleapis/gax-go/v2](https://github.com/googleapis/gax-go) from 2.12.0 to 2.12.2.
- [Release notes](https://github.com/googleapis/gax-go/releases)
- [Commits](https://github.com/googleapis/gax-go/compare/v2.12.0...v2.12.2)

---
updated-dependencies:
- dependency-name: github.com/googleapis/gax-go/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
4 months ago
Herman Slatman bb6aae0dfc
Merge pull request #1736 from patsevanton/master
Сorrection of spelling errors
4 months ago
Anton Patsev c2dfe595f1 Сorrection of spelling errors 4 months ago
Herman Slatman e968275a20
Merge pull request #1729 from patsevanton/master
Spelling errors and punctuation have been corrected
4 months ago
Herman Slatman 7e1b93b628
Update examples/README.md 4 months ago
github-actions[bot] dc577e2213
Merge pull request #1724 from smallstep/dependabot/go_modules/github.com/newrelic/go-agent/v3-3.30.0
Bump github.com/newrelic/go-agent/v3 from 3.29.1 to 3.30.0
4 months ago
dependabot[bot] 3a2b426879
Bump github.com/newrelic/go-agent/v3 from 3.29.1 to 3.30.0
Bumps [github.com/newrelic/go-agent/v3](https://github.com/newrelic/go-agent) from 3.29.1 to 3.30.0.
- [Release notes](https://github.com/newrelic/go-agent/releases)
- [Changelog](https://github.com/newrelic/go-agent/blob/master/CHANGELOG.md)
- [Commits](https://github.com/newrelic/go-agent/compare/v3.29.1...v3.30.0)

---
updated-dependencies:
- dependency-name: github.com/newrelic/go-agent/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
4 months ago
github-actions[bot] f7554a0a43
Merge pull request #1725 from smallstep/dependabot/go_modules/github.com/hashicorp/vault/api/auth/kubernetes-0.6.0
Bump github.com/hashicorp/vault/api/auth/kubernetes from 0.5.0 to 0.6.0
4 months ago
github-actions[bot] 685e107bfe
Merge pull request #1726 from smallstep/dependabot/go_modules/google.golang.org/api-0.165.0
Bump google.golang.org/api from 0.160.0 to 0.165.0
4 months ago
Anton Patsev 0a074cb8ff Spelling errors and punctuation have been corrected 4 months ago
dependabot[bot] 8e1f53857b
Bump google.golang.org/api from 0.160.0 to 0.165.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.160.0 to 0.165.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.160.0...v0.165.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
4 months ago
github-actions[bot] e6491ca28b
Merge pull request #1727 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.43.1
Bump go.step.sm/crypto from 0.43.0 to 0.43.1
4 months ago
dependabot[bot] 507f4d04d3
Bump go.step.sm/crypto from 0.43.0 to 0.43.1
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.43.0 to 0.43.1.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.43.0...v0.43.1)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
4 months ago
dependabot[bot] 2ffc9081e7
Bump github.com/hashicorp/vault/api/auth/kubernetes from 0.5.0 to 0.6.0
Bumps [github.com/hashicorp/vault/api/auth/kubernetes](https://github.com/hashicorp/vault) from 0.5.0 to 0.6.0.
- [Release notes](https://github.com/hashicorp/vault/releases)
- [Changelog](https://github.com/hashicorp/vault/blob/main/CHANGELOG-v0.md)
- [Commits](https://github.com/hashicorp/vault/compare/v0.5.0...v0.6.0)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/vault/api/auth/kubernetes
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
4 months ago
Herman Slatman bb296c9d19
Merge pull request #1708 from smallstep/herman/csr-expires-header
Add `Expires` header to CRL endpoint
4 months ago
Mariano Cano bd99db0071
Merge pull request #1685 from venkyg-sec/allow_custom_tls_config
Allow usage of externally supplied TLS config
4 months ago
Mariano Cano 503e5046ea
Merge branch 'master' into allow_custom_tls_config 4 months ago
Mariano Cano beea482a0c
Fix linter errors in ca/ca.go 4 months ago
Mariano Cano 073fcb7e75
Merge pull request #1684 from venkyg-sec/allow_external_x509_ca_service_intf
Allow x509 Service CA implementation to be injected through ca and authority options
4 months ago
Mariano Cano ac773ff44e
Merge branch 'master' into allow_external_x509_ca_service_intf 4 months ago
Mariano Cano 9fcdd3ffa6
Fix format warnings on ca/ca.go 4 months ago
Herman Slatman 3dbb4aad3d
Change CRL unavailable case to HTTP 404 4 months ago
Herman Slatman 5d865b28d1
Merge pull request #1715 from rvichery/aws-ca-west-1-iid-certificate
Add AWS ca-west-1 identity document certificate
4 months ago
Carl Tashian e542a26d4b
Fix RA installer step-ca package URL 4 months ago
Remi Vichery ee44ac104d
fixup! Add AWS ca-west-1 identity document certificate 4 months ago
github-actions[bot] 490d065c8e
Merge pull request #1713 from smallstep/dependabot/go_modules/github.com/hashicorp/vault/api/auth/approle-0.6.0
Bump github.com/hashicorp/vault/api/auth/approle from 0.5.0 to 0.6.0
4 months ago
Remi Vichery 283d46d9a7
Add AWS ca-west-1 identity document certificate 4 months ago
dependabot[bot] a3bed4095a
Bump github.com/hashicorp/vault/api/auth/approle from 0.5.0 to 0.6.0
Bumps [github.com/hashicorp/vault/api/auth/approle](https://github.com/hashicorp/vault) from 0.5.0 to 0.6.0.
- [Release notes](https://github.com/hashicorp/vault/releases)
- [Changelog](https://github.com/hashicorp/vault/blob/main/CHANGELOG-v0.md)
- [Commits](https://github.com/hashicorp/vault/compare/v0.5.0...v0.6.0)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/vault/api/auth/approle
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
4 months ago
github-actions[bot] d174e78801
Merge pull request #1712 from smallstep/dependabot/go_modules/golang.org/x/net-0.21.0
Bump golang.org/x/net from 0.20.0 to 0.21.0
4 months ago
github-actions[bot] 5f91441d44
Merge pull request #1711 from smallstep/dependabot/go_modules/cloud.google.com/go/longrunning-0.5.5
Bump cloud.google.com/go/longrunning from 0.5.4 to 0.5.5
4 months ago
dependabot[bot] a32dade78d
Bump golang.org/x/net from 0.20.0 to 0.21.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.20.0 to 0.21.0.
- [Commits](https://github.com/golang/net/compare/v0.20.0...v0.21.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
4 months ago
dependabot[bot] b9db4e3fa4
Bump cloud.google.com/go/longrunning from 0.5.4 to 0.5.5
Bumps [cloud.google.com/go/longrunning](https://github.com/googleapis/google-cloud-go) from 0.5.4 to 0.5.5.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/longrunning/v0.5.4...longrunning/v0.5.5)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/longrunning
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
4 months ago
Herman Slatman c76dad8a22
Improve tests for CRL HTTP handler 5 months ago
Herman Slatman 69f5f8d8ea
Use `stretchr/testify` instead of `smallstep/assert` for tests 5 months ago
Herman Slatman d1deb7f930
Add `Expires` header to CRL response 5 months ago
github-actions[bot] 67246925d2
Merge pull request #1706 from smallstep/dependabot/go_modules/github.com/prometheus/client_golang-1.18.0
Bump github.com/prometheus/client_golang from 1.15.1 to 1.18.0
5 months ago
github-actions[bot] 6d29e8ade8
Merge pull request #1704 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.43.0
Bump go.step.sm/crypto from 0.42.1 to 0.43.0
5 months ago
github-actions[bot] 05ccf84623
Merge pull request #1705 from smallstep/dependabot/go_modules/cloud.google.com/go/security-1.15.5
Bump cloud.google.com/go/security from 1.15.4 to 1.15.5
5 months ago
dependabot[bot] 78522c7544
Bump github.com/prometheus/client_golang from 1.15.1 to 1.18.0
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.15.1 to 1.18.0.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.15.1...v1.18.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
5 months ago
dependabot[bot] 053d05b4a1
Bump cloud.google.com/go/security from 1.15.4 to 1.15.5
Bumps [cloud.google.com/go/security](https://github.com/googleapis/google-cloud-go) from 1.15.4 to 1.15.5.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/kms/v1.15.4...kms/v1.15.5)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/security
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
5 months ago
dependabot[bot] 5209393197
Bump go.step.sm/crypto from 0.42.1 to 0.43.0
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.42.1 to 0.43.0.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.42.1...v0.43.0)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
5 months ago
github-actions[bot] 59ea73129a
Merge pull request #1693 from smallstep/dependabot/go_modules/github.com/hashicorp/vault/api-1.11.0
Bump github.com/hashicorp/vault/api from 1.10.0 to 1.11.0
5 months ago
dependabot[bot] 78d889a047
Bump github.com/hashicorp/vault/api from 1.10.0 to 1.11.0
Bumps [github.com/hashicorp/vault/api](https://github.com/hashicorp/vault) from 1.10.0 to 1.11.0.
- [Release notes](https://github.com/hashicorp/vault/releases)
- [Changelog](https://github.com/hashicorp/vault/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/vault/compare/v1.10.0...v1.11.0)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/vault/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
5 months ago
github-actions[bot] 2fcb33bd3a
Merge pull request #1695 from smallstep/dependabot/go_modules/github.com/newrelic/go-agent/v3-3.29.1
Bump github.com/newrelic/go-agent/v3 from 3.29.0 to 3.29.1
5 months ago
github-actions[bot] fe926e9ad6
Merge pull request #1694 from smallstep/dependabot/go_modules/github.com/google/uuid-1.6.0
Bump github.com/google/uuid from 1.5.0 to 1.6.0
5 months ago
github-actions[bot] 8123d6a405
Merge pull request #1692 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.42.1
Bump go.step.sm/crypto from 0.42.0 to 0.42.1
5 months ago
dependabot[bot] d9cf8aa685
Bump github.com/newrelic/go-agent/v3 from 3.29.0 to 3.29.1
Bumps [github.com/newrelic/go-agent/v3](https://github.com/newrelic/go-agent) from 3.29.0 to 3.29.1.
- [Release notes](https://github.com/newrelic/go-agent/releases)
- [Changelog](https://github.com/newrelic/go-agent/blob/master/CHANGELOG.md)
- [Commits](https://github.com/newrelic/go-agent/compare/v3.29.0...v3.29.1)

---
updated-dependencies:
- dependency-name: github.com/newrelic/go-agent/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
5 months ago
dependabot[bot] eeaabbc481
Bump github.com/google/uuid from 1.5.0 to 1.6.0
Bumps [github.com/google/uuid](https://github.com/google/uuid) from 1.5.0 to 1.6.0.
- [Release notes](https://github.com/google/uuid/releases)
- [Changelog](https://github.com/google/uuid/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/uuid/compare/v1.5.0...v1.6.0)

---
updated-dependencies:
- dependency-name: github.com/google/uuid
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
5 months ago
dependabot[bot] 11220903d2
Bump go.step.sm/crypto from 0.42.0 to 0.42.1
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.42.0 to 0.42.1.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.42.0...v0.42.1)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
5 months ago
Panagiotis Siatras dd1ff9c15b
Implementation of the Prometheus endpoint (#1669)
Implementation of the http://{metricsAddress}/metrics Prometheus endpoint.
5 months ago
github-actions[bot] 27ea4de240
Merge pull request #1687 from smallstep/dependabot/go_modules/google.golang.org/api-0.157.0
Bump google.golang.org/api from 0.156.0 to 0.157.0
5 months ago
github-actions[bot] b0833d7992
Merge pull request #1686 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.42.0
Bump go.step.sm/crypto from 0.41.0 to 0.42.0
5 months ago
dependabot[bot] bcaf8a5624
Bump google.golang.org/api from 0.156.0 to 0.157.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.156.0 to 0.157.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.156.0...v0.157.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
5 months ago
dependabot[bot] 18d3b7f61e
Bump go.step.sm/crypto from 0.41.0 to 0.42.0
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.41.0 to 0.42.0.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.41.0...v0.42.0)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
5 months ago
Venky Gopal 356e7070ef Allow usage of externally supplied TLS config 5 months ago
Venky Gopal fbc1e895c2 Allow x509 Service CA implementation to be injected through ca and authority options 5 months ago
github-actions[bot] 3a840bf605
Merge pull request #1676 from smallstep/dependabot/go_modules/google.golang.org/api-0.156.0
Bump google.golang.org/api from 0.155.0 to 0.156.0
5 months ago
dependabot[bot] 5b35f5c2d7
Bump google.golang.org/api from 0.155.0 to 0.156.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.155.0 to 0.156.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.155.0...v0.156.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
5 months ago
github-actions[bot] ff7e2f9c2d
Merge pull request #1675 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.41.0
Bump go.step.sm/crypto from 0.40.0 to 0.41.0
5 months ago
dependabot[bot] ee4f51a7af
Bump go.step.sm/crypto from 0.40.0 to 0.41.0
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.40.0 to 0.41.0.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.40.0...v0.41.0)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
5 months ago
Herman Slatman f1c54d6852
Merge pull request #1665 from smallstep/herman/fix-error-msg-csr-validation
Change error message for CSR validation
6 months ago
Herman Slatman 25c109e75d
Change error message for CSR validation 6 months ago
github-actions[bot] fc55fba5b5
Merge pull request #1664 from smallstep/dependabot/go_modules/google.golang.org/api-0.155.0
Bump google.golang.org/api from 0.154.0 to 0.155.0
6 months ago
Herman Slatman 4ba2e22b8d
Merge pull request #1663 from smallstep/herman/acme-cose-rs1-support 6 months ago
dependabot[bot] a49d1f7dc0
Bump google.golang.org/api from 0.154.0 to 0.155.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.154.0 to 0.155.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.154.0...v0.155.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
6 months ago
Herman Slatman e52836f0ab
Add `RS1` support for ACME `device-attest-01` 6 months ago
Herman Slatman 581db00a00
Merge pull request #1661 from smallstep/herman/acme-challenge-client-proxy
Add support for `HTTP_PROXY` and `HTTPS_PROXY` to ACME solver client
6 months ago
Herman Slatman c59d293d26
Add support for `HTTP_PROXY` and `HTTPS_PROXY` to ACME solver client 6 months ago
github-actions[bot] b75773e193
Merge pull request #1655 from smallstep/dependabot/go_modules/google.golang.org/protobuf-1.32.0
Bump google.golang.org/protobuf from 1.31.0 to 1.32.0
6 months ago
github-actions[bot] 5432316f2c
Merge pull request #1657 from smallstep/dependabot/go_modules/github.com/go-chi/chi/v5-5.0.11
Bump github.com/go-chi/chi/v5 from 5.0.10 to 5.0.11
6 months ago
dependabot[bot] a612efff5a
Bump google.golang.org/protobuf from 1.31.0 to 1.32.0
Bumps google.golang.org/protobuf from 1.31.0 to 1.32.0.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
6 months ago
github-actions[bot] 428404870e
Merge pull request #1654 from smallstep/dependabot/go_modules/google.golang.org/grpc-1.60.1
Bump google.golang.org/grpc from 1.60.0 to 1.60.1
6 months ago
dependabot[bot] f3572b39c6
Bump github.com/go-chi/chi/v5 from 5.0.10 to 5.0.11
Bumps [github.com/go-chi/chi/v5](https://github.com/go-chi/chi) from 5.0.10 to 5.0.11.
- [Release notes](https://github.com/go-chi/chi/releases)
- [Changelog](https://github.com/go-chi/chi/blob/master/CHANGELOG.md)
- [Commits](https://github.com/go-chi/chi/compare/v5.0.10...v5.0.11)

---
updated-dependencies:
- dependency-name: github.com/go-chi/chi/v5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
6 months ago
dependabot[bot] e45be31055
Bump google.golang.org/grpc from 1.60.0 to 1.60.1
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.60.0 to 1.60.1.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.60.0...v1.60.1)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
6 months ago
github-actions[bot] 4a580f59fb
Merge pull request #1649 from smallstep/dependabot/go_modules/google.golang.org/api-0.154.0
Bump google.golang.org/api from 0.153.0 to 0.154.0
6 months ago
dependabot[bot] 56daa26900
Bump google.golang.org/api from 0.153.0 to 0.154.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.153.0 to 0.154.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.153.0...v0.154.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
6 months ago
github-actions[bot] 9eecd12fc2
Merge pull request #1651 from smallstep/dependabot/go_modules/github.com/newrelic/go-agent/v3-3.29.0
Bump github.com/newrelic/go-agent/v3 from 3.28.1 to 3.29.0
6 months ago
github-actions[bot] 40c58cb1ec
Merge pull request #1650 from smallstep/dependabot/go_modules/google.golang.org/grpc-1.60.0
Bump google.golang.org/grpc from 1.59.0 to 1.60.0
6 months ago
github-actions[bot] 9780cf7b80
Merge pull request #1648 from smallstep/dependabot/go_modules/github.com/google/uuid-1.5.0
Bump github.com/google/uuid from 1.4.0 to 1.5.0
6 months ago
github-actions[bot] 0e3964ee80
Merge pull request #1652 from smallstep/dependabot/go_modules/golang.org/x/crypto-0.17.0
Bump golang.org/x/crypto from 0.16.0 to 0.17.0
6 months ago
dependabot[bot] 5d446dedd6
Bump golang.org/x/crypto from 0.16.0 to 0.17.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.16.0 to 0.17.0.
- [Commits](https://github.com/golang/crypto/compare/v0.16.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
6 months ago
dependabot[bot] 46237b8638
Bump github.com/newrelic/go-agent/v3 from 3.28.1 to 3.29.0
Bumps [github.com/newrelic/go-agent/v3](https://github.com/newrelic/go-agent) from 3.28.1 to 3.29.0.
- [Release notes](https://github.com/newrelic/go-agent/releases)
- [Changelog](https://github.com/newrelic/go-agent/blob/master/CHANGELOG.md)
- [Commits](https://github.com/newrelic/go-agent/compare/v3.28.1...v3.29.0)

---
updated-dependencies:
- dependency-name: github.com/newrelic/go-agent/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
6 months ago
dependabot[bot] 33e6f2bae2
Bump google.golang.org/grpc from 1.59.0 to 1.60.0
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.59.0 to 1.60.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.59.0...v1.60.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
6 months ago
dependabot[bot] 2a5a65161c
Bump github.com/google/uuid from 1.4.0 to 1.5.0
Bumps [github.com/google/uuid](https://github.com/google/uuid) from 1.4.0 to 1.5.0.
- [Release notes](https://github.com/google/uuid/releases)
- [Changelog](https://github.com/google/uuid/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/uuid/compare/v1.4.0...v1.5.0)

---
updated-dependencies:
- dependency-name: github.com/google/uuid
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
6 months ago
Mariano Cano 62e09de2c6
Merge pull request #1647 from smallstep/go-jose
Upgrade go.step.sm/crypto to use go-jose/v3
7 months ago
Mariano Cano b20af51f32
Upgrade go.step.sm/crypto to use go-jose/v3 7 months ago
github-actions[bot] 2c42907b4e
Merge pull request #1645 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.39.0
Bump go.step.sm/crypto from 0.38.0 to 0.39.0
7 months ago
github-actions[bot] ecc47c8e18
Merge pull request #1646 from smallstep/dependabot/go_modules/google.golang.org/api-0.153.0
Bump google.golang.org/api from 0.152.0 to 0.153.0
7 months ago
Carl Tashian 4d0c684e88
Merge pull request #1640 from smallstep/carl/debian-bookworm
Update Dockerfile.hsm to use Debian bookworm
7 months ago
dependabot[bot] 6fcfb7a737
Bump google.golang.org/api from 0.152.0 to 0.153.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.152.0 to 0.153.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.152.0...v0.153.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
7 months ago
dependabot[bot] 9aee8fde06
Bump go.step.sm/crypto from 0.38.0 to 0.39.0
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.38.0 to 0.39.0.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.38.0...v0.39.0)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
7 months ago
Carl Tashian bd46d94238
Merge branch 'master' into carl/debian-bookworm 7 months ago
github-actions[bot] c25273d7a7
Merge pull request #1638 from smallstep/dependabot/go_modules/github.com/newrelic/go-agent/v3-3.28.1
Bump github.com/newrelic/go-agent/v3 from 3.28.0 to 3.28.1
7 months ago
Carl Tashian 38140c5765
Update Dockerfile.hsm to use Debian bookworm 7 months ago
dependabot[bot] 439ace3086
Bump github.com/newrelic/go-agent/v3 from 3.28.0 to 3.28.1
Bumps [github.com/newrelic/go-agent/v3](https://github.com/newrelic/go-agent) from 3.28.0 to 3.28.1.
- [Release notes](https://github.com/newrelic/go-agent/releases)
- [Changelog](https://github.com/newrelic/go-agent/blob/master/CHANGELOG.md)
- [Commits](https://github.com/newrelic/go-agent/compare/v3.28.0...v3.28.1)

---
updated-dependencies:
- dependency-name: github.com/newrelic/go-agent/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
7 months ago
Herman Slatman f453323ba9
Merge pull request #1631 from smallstep/herman/fix-apple-acmeclient-invalid-signatures 7 months ago
Herman Slatman 405aae798c
Simplify the `copy` logic used when patching JWS signature 7 months ago
Max 7bfe11c687
Bump go.step.sm/crypto (#1635) 7 months ago
Max d34f0f6a97
Fix linter warnings (#1634) 7 months ago
Herman Slatman 26a3bb3c11
Make the Apple JWS fix more robust and catch more cases. 7 months ago
Herman Slatman 31ba1b33fb
Merge pull request #1633 from smallstep/update-changelog-20231122
Set `v0.25.1` release date
7 months ago
Herman Slatman 528aad86dd
Set `v0.25.1` release date 7 months ago
Herman Slatman 3bb469274d
Merge pull request #1632 from smallstep/update-changelog-20231122
Update changelog for `v0.25.1` release
7 months ago
Herman Slatman f01b48fdcd
Update changelog for `v0.25.1` release 7 months ago
Herman Slatman 113491e7af
Remove TODO for patching other algorithms for Apple ACME client 7 months ago
Herman Slatman 06f4cbbcda
Add (temporary) fix for missing null bytes in Apple JWS signatures
Apparently the Apple macOS (and iOS?) ACME client seems to omit
leading null bytes from JWS signatures. The base64-url encoded
bytes decode to a shorter byte slice than what the JOSE library
expects (e.g. 63 bytes instead of 64 bytes for ES256), and then
results in a `jose.ErrCryptoFailure`.

This commit retries verification of the JWS in case the first
verification fails with `jose.ErrCryptoFailure`. The signatures are
checked to be of the correct length, and if not, null bytes are
prepended to the signature. Then verification is retried, which
might fail again, but for other reasons. On success, the payload
is returned.

Apple should fix this in their ACME client, but in the meantime
this commit prevents some "bad request" error cases from happening.
7 months ago
github-actions[bot] cf6e189d7c
Merge pull request #1629 from smallstep/dependabot/go_modules/github.com/go-jose/go-jose/v3-3.0.1
Bump github.com/go-jose/go-jose/v3 from 3.0.0 to 3.0.1
7 months ago
dependabot[bot] 350ad9006c
Bump github.com/go-jose/go-jose/v3 from 3.0.0 to 3.0.1
Bumps [github.com/go-jose/go-jose/v3](https://github.com/go-jose/go-jose) from 3.0.0 to 3.0.1.
- [Release notes](https://github.com/go-jose/go-jose/releases)
- [Changelog](https://github.com/go-jose/go-jose/blob/v3/CHANGELOG.md)
- [Commits](https://github.com/go-jose/go-jose/compare/v3.0.0...v3.0.1)

---
updated-dependencies:
- dependency-name: github.com/go-jose/go-jose/v3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
7 months ago
github-actions[bot] 1dacf50776
Merge pull request #1626 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.37.0
Bump go.step.sm/crypto from 0.36.1 to 0.37.0
7 months ago
dependabot[bot] 66df354f2f
Bump go.step.sm/crypto from 0.36.1 to 0.37.0
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.36.1 to 0.37.0.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.36.1...v0.37.0)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
7 months ago
github-actions[bot] c6db7673bf
Merge pull request #1628 from smallstep/dependabot/go_modules/google.golang.org/api-0.151.0
Bump google.golang.org/api from 0.150.0 to 0.151.0
7 months ago
github-actions[bot] a36cf81d6a
Merge pull request #1627 from smallstep/dependabot/go_modules/github.com/newrelic/go-agent/v3-3.28.0
Bump github.com/newrelic/go-agent/v3 from 3.27.0 to 3.28.0
7 months ago
dependabot[bot] 5b07ae7f52
Bump google.golang.org/api from 0.150.0 to 0.151.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.150.0 to 0.151.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.150.0...v0.151.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
7 months ago
dependabot[bot] 74597e6fbb
Bump github.com/newrelic/go-agent/v3 from 3.27.0 to 3.28.0
Bumps [github.com/newrelic/go-agent/v3](https://github.com/newrelic/go-agent) from 3.27.0 to 3.28.0.
- [Release notes](https://github.com/newrelic/go-agent/releases)
- [Changelog](https://github.com/newrelic/go-agent/blob/master/CHANGELOG.md)
- [Commits](https://github.com/newrelic/go-agent/compare/v3.27.0...v3.28.0)

---
updated-dependencies:
- dependency-name: github.com/newrelic/go-agent/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
7 months ago
github-actions[bot] 8308e1ac54
Merge pull request #1619 from smallstep/dependabot/go_modules/golang.org/x/net-0.18.0
Bump golang.org/x/net from 0.17.0 to 0.18.0
8 months ago
dependabot[bot] 6826ca9ebb
Bump golang.org/x/net from 0.17.0 to 0.18.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.17.0 to 0.18.0.
- [Commits](https://github.com/golang/net/compare/v0.17.0...v0.18.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
8 months ago
github-actions[bot] 4f6ca083aa
Merge pull request #1620 from smallstep/dependabot/go_modules/golang.org/x/crypto-0.15.0
Bump golang.org/x/crypto from 0.14.0 to 0.15.0
8 months ago
dependabot[bot] 2eefd2ce63
Bump golang.org/x/crypto from 0.14.0 to 0.15.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.14.0 to 0.15.0.
- [Commits](https://github.com/golang/crypto/compare/v0.14.0...v0.15.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
8 months ago
github-actions[bot] 6ebd5264ec
Merge pull request #1621 from smallstep/dependabot/go_modules/google.golang.org/api-0.150.0
Bump google.golang.org/api from 0.149.0 to 0.150.0
8 months ago
dependabot[bot] 48d9ea188b
Bump google.golang.org/api from 0.149.0 to 0.150.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.149.0 to 0.150.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.149.0...v0.150.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
8 months ago
Herman Slatman a4b7bbf2d9
Merge pull request #1617 from smallstep/herman/scep-webhook-provisioner-name
Add `provisionerName` to SCEP webhook request body
8 months ago
Herman Slatman f082cbc421
Denormalize provisioner name in SCEP webhook 8 months ago
Herman Slatman 9ebc8779f5
Normalize SCEP provisioner name in webhook body 8 months ago
Herman Slatman e815864ed8
Add verification of `provisionerName` in test 8 months ago
Herman Slatman de45d66cdb
Add `provisionerName` to webhook request body 8 months ago
Mariano Cano a7ed79bb21
Merge pull request #1616 from smallstep/fix-1611
Use the same version for building and running
8 months ago
Mariano Cano 875512c79e
Use the same version for building and running
This commit makes sure to use the same version for building step-ca with
CGO and running it.

Fixes #1611
8 months ago
Mariano Cano 1697dc63a7
Merge pull request #1608 from smallstep/mariano/ra-template
Build RA token using SANs from the template
8 months ago
Mariano Cano 690d1c3c50
Merge pull request #1609 from smallstep/mariano/jwk-commonname
Change CommonName validator in JWK
8 months ago
github-actions[bot] 111bc1d789
Merge pull request #1613 from smallstep/dependabot/go_modules/cloud.google.com/go/longrunning-0.5.4
Bump cloud.google.com/go/longrunning from 0.5.3 to 0.5.4
8 months ago
dependabot[bot] 8c5d26e1c5
Bump cloud.google.com/go/longrunning from 0.5.3 to 0.5.4
Bumps [cloud.google.com/go/longrunning](https://github.com/googleapis/google-cloud-go) from 0.5.3 to 0.5.4.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/longrunning/v0.5.3...longrunning/v0.5.4)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/longrunning
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
8 months ago
github-actions[bot] 444cfe2fcd
Merge pull request #1614 from smallstep/dependabot/go_modules/cloud.google.com/go/security-1.15.4
Bump cloud.google.com/go/security from 1.15.3 to 1.15.4
8 months ago
dependabot[bot] 8406f75806
Bump cloud.google.com/go/security from 1.15.3 to 1.15.4
Bumps [cloud.google.com/go/security](https://github.com/googleapis/google-cloud-go) from 1.15.3 to 1.15.4.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/kms/v1.15.3...kms/v1.15.4)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/security
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
8 months ago
Herman Slatman 132e888f36
Merge pull request #1610 from abelgvidal/fixcontrib
Amend link to Contribution Guide in README
8 months ago
Abel Gonzalez 807c7562f5 Amend wrong link to Contribution Guide in README 8 months ago
Mariano Cano 49045a1150
Change CommonName validator in JWK
This commit changes the common name validator in the JWK provisioner to
accept either the token subject or any of the sans in the token.
8 months ago
Mariano Cano 6705b7dde4
Build RA token using SANs from the template
This commit updates the RA token to use the SANs coming from the
template instead of the CSR.

Note that this PR might break some admin tokens.
8 months ago
github-actions[bot] ef2b43d888
Merge pull request #1604 from smallstep/dependabot/go_modules/cloud.google.com/go/security-1.15.3
Bump cloud.google.com/go/security from 1.15.2 to 1.15.3
8 months ago
dependabot[bot] 3528012614
Bump cloud.google.com/go/security from 1.15.2 to 1.15.3
Bumps [cloud.google.com/go/security](https://github.com/googleapis/google-cloud-go) from 1.15.2 to 1.15.3.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/kms/v1.15.2...kms/v1.15.3)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/security
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
8 months ago
github-actions[bot] a278e707e8
Merge pull request #1605 from smallstep/dependabot/go_modules/github.com/google/uuid-1.4.0
Bump github.com/google/uuid from 1.3.1 to 1.4.0
8 months ago
github-actions[bot] 7043ff1464
Merge pull request #1606 from smallstep/dependabot/go_modules/cloud.google.com/go/longrunning-0.5.3
Bump cloud.google.com/go/longrunning from 0.5.2 to 0.5.3
8 months ago
dependabot[bot] 15383bae66
Bump cloud.google.com/go/longrunning from 0.5.2 to 0.5.3
Bumps [cloud.google.com/go/longrunning](https://github.com/googleapis/google-cloud-go) from 0.5.2 to 0.5.3.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/longrunning/v0.5.2...longrunning/v0.5.3)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/longrunning
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
8 months ago
dependabot[bot] 4c51360400
Bump github.com/google/uuid from 1.3.1 to 1.4.0
Bumps [github.com/google/uuid](https://github.com/google/uuid) from 1.3.1 to 1.4.0.
- [Release notes](https://github.com/google/uuid/releases)
- [Changelog](https://github.com/google/uuid/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/uuid/compare/v1.3.1...v1.4.0)

---
updated-dependencies:
- dependency-name: github.com/google/uuid
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
8 months ago
Herman Slatman 71a4481e57
Merge pull request #1600 from smallstep/herman/use-smallstep-scep-and-pkcs7
Use Smallstep SCEP and PKCS7 libraries
8 months ago
Herman Slatman af649018a2
Merge branch 'master' into herman/use-smallstep-scep-and-pkcs7 8 months ago
Herman Slatman 1abada69b0
Update import aliases from `microscep` to `smallscep` 8 months ago
Herman Slatman 4c17f25389
Replace MicroMDM and Mozilla libraries with Smallstep forks 8 months ago
github-actions[bot] 5e70d6fc81
Merge pull request #1597 from smallstep/dependabot/go_modules/github.com/newrelic/go-agent/v3-3.27.0
Bump github.com/newrelic/go-agent/v3 from 3.26.0 to 3.27.0
8 months ago
github-actions[bot] 27fdfca7c8
Merge pull request #1595 from smallstep/dependabot/go_modules/google.golang.org/grpc-1.59.0
Bump google.golang.org/grpc from 1.58.3 to 1.59.0
8 months ago
dependabot[bot] 352979ac23
Bump google.golang.org/grpc from 1.58.3 to 1.59.0
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.58.3 to 1.59.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.58.3...v1.59.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
8 months ago
github-actions[bot] 0425a0c86c
Merge pull request #1596 from smallstep/dependabot/go_modules/google.golang.org/api-0.148.0
Bump google.golang.org/api from 0.147.0 to 0.148.0
8 months ago
dependabot[bot] 756bec0df8
Bump google.golang.org/api from 0.147.0 to 0.148.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.147.0 to 0.148.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.147.0...v0.148.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
8 months ago
dependabot[bot] 16f1606ad4
Bump github.com/newrelic/go-agent/v3 from 3.26.0 to 3.27.0
Bumps [github.com/newrelic/go-agent/v3](https://github.com/newrelic/go-agent) from 3.26.0 to 3.27.0.
- [Release notes](https://github.com/newrelic/go-agent/releases)
- [Changelog](https://github.com/newrelic/go-agent/blob/master/CHANGELOG.md)
- [Commits](https://github.com/newrelic/go-agent/compare/v3.26.0...v3.27.0)

---
updated-dependencies:
- dependency-name: github.com/newrelic/go-agent/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
8 months ago
Max c451546cfb
[action] fix actionlint warnings (#1598) 8 months ago
Mariano Cano 96c87bb99e
Merge pull request #1590 from smallstep/mariano/asn1-bool
Upgrade go.step.sm/crypto with ASN.1 bool support
8 months ago
Mariano Cano ad22f149b7
Upgrade go.step.sm/crypto with ASN.1 bool support
This commit upgrades go.step.sm/crypto dependency with a version that
adds support of ASN.1 boolean encoding.
8 months ago
Carl Tashian 5d10e54551
Merge pull request #1580 from smallstep/carl/unversioned
Wrap unversioned step-ca binary into an unversioned dir
8 months ago
github-actions[bot] 06baf58c9f
Merge pull request #1588 from smallstep/dependabot/github_actions/dependabot/fetch-metadata-1.6.0
Bump dependabot/fetch-metadata from 1.1.1 to 1.6.0
8 months ago
github-actions[bot] d5663ef021
Merge pull request #1589 from smallstep/dependabot/go_modules/google.golang.org/api-0.147.0
Bump google.golang.org/api from 0.145.0 to 0.147.0
8 months ago
dependabot[bot] d5f17908a3
Bump google.golang.org/api from 0.145.0 to 0.147.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.145.0 to 0.147.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.145.0...v0.147.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
8 months ago
dependabot[bot] f548c13e3e
Bump dependabot/fetch-metadata from 1.1.1 to 1.6.0
Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 1.1.1 to 1.6.0.
- [Release notes](https://github.com/dependabot/fetch-metadata/releases)
- [Commits](https://github.com/dependabot/fetch-metadata/compare/v1.1.1...v1.6.0)

---
updated-dependencies:
- dependency-name: dependabot/fetch-metadata
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
8 months ago
Max 830f31c6d1
[action] add dependabot updates for github actions (#1586) 8 months ago
github-actions[bot] 819a4d7d6b
Merge pull request #1584 from smallstep/dependabot/go_modules/cloud.google.com/go/security-1.15.2
Bump cloud.google.com/go/security from 1.15.1 to 1.15.2
8 months ago
github-actions[bot] f8ae8f252e
Merge pull request #1582 from smallstep/dependabot/go_modules/google.golang.org/grpc-1.58.3
Bump google.golang.org/grpc from 1.58.2 to 1.58.3
8 months ago
github-actions[bot] 7008feae30
Merge pull request #1583 from smallstep/dependabot/go_modules/github.com/google/go-cmp-0.6.0
Bump github.com/google/go-cmp from 0.5.9 to 0.6.0
8 months ago
github-actions[bot] c70c092557
Merge pull request #1585 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.36.0
Bump go.step.sm/crypto from 0.35.1 to 0.36.0
8 months ago
dependabot[bot] 2574555672
Bump cloud.google.com/go/security from 1.15.1 to 1.15.2
Bumps [cloud.google.com/go/security](https://github.com/googleapis/google-cloud-go) from 1.15.1 to 1.15.2.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/kms/v1.15.1...kms/v1.15.2)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/security
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
8 months ago
github-actions[bot] 3a633c1cf6
Merge pull request #1581 from smallstep/dependabot/go_modules/cloud.google.com/go/longrunning-0.5.2
Bump cloud.google.com/go/longrunning from 0.5.1 to 0.5.2
8 months ago
dependabot[bot] d66ddf890c
Bump go.step.sm/crypto from 0.35.1 to 0.36.0
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.35.1 to 0.36.0.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.35.1...v0.36.0)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
8 months ago
dependabot[bot] 7ada4cac91
Bump github.com/google/go-cmp from 0.5.9 to 0.6.0
Bumps [github.com/google/go-cmp](https://github.com/google/go-cmp) from 0.5.9 to 0.6.0.
- [Release notes](https://github.com/google/go-cmp/releases)
- [Commits](https://github.com/google/go-cmp/compare/v0.5.9...v0.6.0)

---
updated-dependencies:
- dependency-name: github.com/google/go-cmp
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
8 months ago
dependabot[bot] 6d6b8882ad
Bump google.golang.org/grpc from 1.58.2 to 1.58.3
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.58.2 to 1.58.3.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.58.2...v1.58.3)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
8 months ago
dependabot[bot] c6daca0c2e
Bump cloud.google.com/go/longrunning from 0.5.1 to 0.5.2
Bumps [cloud.google.com/go/longrunning](https://github.com/googleapis/google-cloud-go) from 0.5.1 to 0.5.2.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/dataflow/v0.5.1...longrunning/v0.5.2)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/longrunning
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
8 months ago
Carl Tashian de1dc6838f
Wrap unversioned step into an unversioned dir 9 months ago
Carl Tashian 63aa894525
Wrap unversioned step into an unversioned dir 9 months ago
Mariano Cano f7836a0664
Merge pull request #1578 from smallstep/upgrade-x-net-http2
Upgrades golang.org/x/net/http2
9 months ago
Mariano Cano 532fc228d3
Upgrades golang.org/x/net/http2
Although step-ca doesn't manually configure HTTP/2, the new version
fixes the issue described in https://go.dev/issue/63417.
9 months ago
github-actions[bot] 95bf3d60ef
Merge pull request #1574 from smallstep/dependabot/go_modules/golang.org/x/net-0.16.0
Bump golang.org/x/net from 0.15.0 to 0.16.0
9 months ago
dependabot[bot] bf7aa211eb
Bump golang.org/x/net from 0.15.0 to 0.16.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.15.0 to 0.16.0.
- [Commits](https://github.com/golang/net/compare/v0.15.0...v0.16.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
9 months ago
github-actions[bot] 06174b9ea7
Merge pull request #1575 from smallstep/dependabot/go_modules/google.golang.org/api-0.145.0
Bump google.golang.org/api from 0.143.0 to 0.145.0
9 months ago
dependabot[bot] 51612b6345
Bump google.golang.org/api from 0.143.0 to 0.145.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.143.0 to 0.145.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.143.0...v0.145.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
9 months ago
Max 9f84f7ce35
Allow for identity certificate signing (in sshSign) by skipping validators (#1572)
- skip urisValidator for identity certificate signing. Implemented
  by building the validator with the context in a hacky way.
9 months ago
Herman Slatman 06750b03fe
Merge pull request #1566 from smallstep/herman/fix-init-with-duplicate-provisioner-name
Fix `step ca init` with duplicate provisioner name (`--provisioner acme --acme`)
9 months ago
Herman Slatman d1dd1fa69c
Merge pull request #1570 from smallstep/herman/improve-scep-request-handling
Improve SCEP request handling
9 months ago
Herman Slatman 25f4b4014d
Add `base64` to the raw message decoding error 9 months ago
Herman Slatman 965d7aa7f4
Fix linting issues 9 months ago
Herman Slatman cd78b9fd43
Implement workaround for weird macOS SCEP message in query
Apparently the macOS SCEP client sends a SCEP message in the query
that's not fully escaped. Only the base64 padding is escaped, the
'+' and '/' characters aren't.

This is a bit of a special case, because the macOS SCEP client
will default to using HTTP POST for the PKIOperation. But if the
CA is configured without the POSTPKIOperation capability, the
macOS SCEP client will use HTTP GET instead. This behavior might
be the same on iOS.
9 months ago
Herman Slatman 3c12b4f5ad
Improve decoding SCEP requests 9 months ago
github-actions[bot] 829de7cf58
Merge pull request #1568 from smallstep/dependabot/go_modules/google.golang.org/api-0.143.0
Bump google.golang.org/api from 0.142.0 to 0.143.0
9 months ago
github-actions[bot] 2e4bb34363
Merge pull request #1567 from smallstep/dependabot/go_modules/github.com/newrelic/go-agent/v3-3.26.0
Bump github.com/newrelic/go-agent/v3 from 3.25.1 to 3.26.0
9 months ago
dependabot[bot] 08dcf39cf7
Bump google.golang.org/api from 0.142.0 to 0.143.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.142.0 to 0.143.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.142.0...v0.143.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
9 months ago
dependabot[bot] 9e0abb7c1d
Bump github.com/newrelic/go-agent/v3 from 3.25.1 to 3.26.0
Bumps [github.com/newrelic/go-agent/v3](https://github.com/newrelic/go-agent) from 3.25.1 to 3.26.0.
- [Release notes](https://github.com/newrelic/go-agent/releases)
- [Changelog](https://github.com/newrelic/go-agent/blob/master/CHANGELOG.md)
- [Commits](https://github.com/newrelic/go-agent/compare/v3.25.1...v3.26.0)

---
updated-dependencies:
- dependency-name: github.com/newrelic/go-agent/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
9 months ago
Herman Slatman 2e560caf68
Add some basic tests for `GenerateConfig`
So far the `GenerateConfig` method wasn't tested. This commit adds
a couple of basic tests for this method. It's not fully covered yet,
nor are all properties being checked, but it provides a starting
point for refactoring the CA (configuration) initialization process.
9 months ago
Herman Slatman 991a9a6223
Merge branch 'master' into herman/fix-init-with-duplicate-provisioner-name 9 months ago
Herman Slatman 3c084822b3
Prevent invalid provisioner name on `step ca init`
An unfortunate combination of `--provisioner acme` and the `--acme`
flags on `step ca init` could lead to an invalidat CA configuration.
This commit prevent this case from happening. A similar error could
occur for the `sshpop` provisioner, so a fix was implemented for that
case too.

The fix doesn't catch all cases, e.g. it doesn't check for multiple
provisioners having the same `acme-` or `sshpop-` prefix. The code
that is called is intended to be only called from a `step ca init`
invocation, so should work for these cases, but might not if the
methods are invoked at other times.
9 months ago
Max 454cec7cdc
Remove gitleaks ignore file (#1565) 9 months ago
Max 5758657b53
[action] remove gitleaks key from code-scan-cron (#1564) 9 months ago
Carl Tashian 88dda9cd37
Merge pull request #1563 from smallstep/carl/fix-cosign-regexp
Fix cosign identity regexp
9 months ago
Carl Tashian 13db94721a
Fix cosign identity regexp 9 months ago
Carl Tashian c1d0a90db5
Merge pull request #1562 from smallstep/carl/winget-pr
Small tweaks to Winget & Scoop configs
9 months ago
Carl Tashian aa6de4059f
Small tweaks to Winget & Scoop configs 9 months ago
Max 4e3b344b00
Update changelog for 0.25.0 release (#1561) 9 months ago
Mariano Cano f9db22d311
Merge pull request #1555 from smallstep/scep-password
Change scep password type to string
9 months ago
Mariano Cano 86c029df36
Merge pull request #1559 from smallstep/no-color
Allow to disable color in the text formatter
9 months ago
Mariano Cano 00d8d8f995
Allow to disable color in the text formatter
This commit adds support for NO_COLOR environment variable, if this is
set, colors will be disabled in the logrus text formatter.

This commit also adds support for the environment variables supported by
logrus, CLICOLOR and CLICOLOR_FORCE

Related to #1549
9 months ago
Mariano Cano 52baf52f84
Change scep password type to string
This commit changes the type of the decrypter key password to string to
be consistent with other passwords in the ca.json
9 months ago
Mariano Cano b66a92ca41
Merge pull request #1414 from smallstep/herman/scep-provisioner-decrypter
Add SCEP provisioner decrypter
9 months ago
Mariano Cano 8fdcbd3ad0
Merge pull request #1554 from smallstep/fix-redacted-types
Fix redacted types in SCEP provisioner
9 months ago
Mariano Cano 33bdae4a34
Fix redacted tests 9 months ago
Mariano Cano 4d5fbfa439
Fix redacted types in SCEP provisioner
This commit uses the same types for the fields in the provisioner.SCEP
type and the "redacted" models.SCEP.
9 months ago
Herman Slatman f505acbaa3
Merge pull request #1553 from smallstep/herman/change-scep-authority-initialization
Change SCEP authority initialization
9 months ago
Herman Slatman c0fbace882
Address review remarks 9 months ago
Herman Slatman 4dc5a688fd
Set SCEP authority options once 9 months ago
Herman Slatman 15c46ebbaa
Switch logic for SCEP initialization around 9 months ago
Herman Slatman f1da256ca4
Change SCEP authority initialization 9 months ago
Herman Slatman 0a5ae396c7
Merge branch 'master' into herman/scep-provisioner-decrypter 9 months ago
Herman Slatman 4554f86f16
Make SCEP decrypter properties use `omitempty` 9 months ago
Herman Slatman aea3f752bd
Upgrade to linkedca v0.20.1 9 months ago
github-actions[bot] 8989dbdb82
Merge pull request #1550 from smallstep/dependabot/go_modules/github.com/newrelic/go-agent/v3-3.25.1
Bump github.com/newrelic/go-agent/v3 from 3.24.1 to 3.25.1
9 months ago
github-actions[bot] eba23216d7
Merge pull request #1552 from smallstep/dependabot/go_modules/google.golang.org/api-0.142.0
Bump google.golang.org/api from 0.141.0 to 0.142.0
9 months ago
dependabot[bot] f1b40a7dfb
Bump google.golang.org/api from 0.141.0 to 0.142.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.141.0 to 0.142.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.141.0...v0.142.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
9 months ago
github-actions[bot] 0d430d4cdf
Merge pull request #1551 from smallstep/dependabot/go_modules/google.golang.org/grpc-1.58.2
Bump google.golang.org/grpc from 1.58.1 to 1.58.2
9 months ago
dependabot[bot] 44662c6544
Bump google.golang.org/grpc from 1.58.1 to 1.58.2
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.58.1 to 1.58.2.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.58.1...v1.58.2)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
9 months ago
dependabot[bot] 4df79cc974
Bump github.com/newrelic/go-agent/v3 from 3.24.1 to 3.25.1
Bumps [github.com/newrelic/go-agent/v3](https://github.com/newrelic/go-agent) from 3.24.1 to 3.25.1.
- [Release notes](https://github.com/newrelic/go-agent/releases)
- [Changelog](https://github.com/newrelic/go-agent/blob/master/CHANGELOG.md)
- [Commits](https://github.com/newrelic/go-agent/compare/v3.24.1...v3.25.1)

---
updated-dependencies:
- dependency-name: github.com/newrelic/go-agent/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
9 months ago
Herman Slatman ffe079f31b
Merge branch 'master' into herman/scep-provisioner-decrypter 9 months ago
Herman Slatman 0d66158bf1
Merge pull request #1544 from smallstep/herman/scep-notifying-webhook
Add SCEP issuance notification webhook
9 months ago
Mariano Cano e766ca7a38
Merge pull request #1546 from smallstep/fix-webhook-signature
Fix webhooks signature
9 months ago
Mariano Cano 31da66c124
Fix webhooks signature
This commit fixes the way webhooks signatures are created. Before this
change, the signature of an empty body was prepended by the body itself.
9 months ago
Herman Slatman 68a1c859b0
Merge pull request #1543 from dnwe/chi
chore(deps): upgrade github.com/go-chi/chi to v5
9 months ago
Herman Slatman 3f3b67e05c
Merge branch 'herman/scep-provisioner-decrypter' into herman/scep-notifying-webhook 9 months ago
Herman Slatman ba72710e2d
Address code review remarks 9 months ago
Herman Slatman 5f8e0de1c3
Fix duplicate import in SCEP provisioner 9 months ago
Herman Slatman 4fd4227b73
Use shorter SCEP decrypter property names from linkedca 9 months ago
Herman Slatman 5fd70af2c8
Make API responses aware of the new SCEP decrypter properties 9 months ago
Herman Slatman 3ade92f8d5
Support both a decrypter key URI as well as PEM 9 months ago
Herman Slatman 6d2d21e989
Fix undefined and unused variables
Forgot to save the latest version...
9 months ago
Herman Slatman b6c95d7be2
Add additional properties to SCEP notify webhook request body 9 months ago
Herman Slatman 63257e0576
Add full certificate DER bytes to success notification webhook 9 months ago
Herman Slatman 52bc96760b
Add SCEP certificate issuance notification webhook 9 months ago
Herman Slatman a3c9dd796a
Merge branch 'herman/scep-provisioner-decrypter' of github.com:smallstep/certificates into herman/scep-provisioner-decrypter 9 months ago
Herman Slatman 69a53eec33
Merge branch 'master' into herman/scep-provisioner-decrypter 9 months ago
Dominic Evans 231b5d8406 chore(deps): upgrade github.com/go-chi/chi to v5
Upgrade chi to the v5 module path to avoid deprecation warning about v4
and earlier on the old module path.

See https://github.com/go-chi/chi/blob/v4.1.3/go.mod#L1-L4

Signed-off-by: Dominic Evans <dominic.evans@uk.ibm.com>
9 months ago
Herman Slatman 09cc834ffa
Merge pull request #1541 from smallstep/herman/fix-go-tpm-0.9.0
Upgrade go-tpm to v0.9.0
9 months ago
Herman Slatman 4ef093dc4b
Fix broken tests relying on `Sign` in mocks 9 months ago
Herman Slatman 9e3807eaa3
Use `SignWithContext` in the critical paths 9 months ago
Herman Slatman 4e06bdbc51
Add `SignWithContext` method to authority and mocks 9 months ago
Herman Slatman b2301ea127
Remove the webhook `Do` method 9 months ago
Herman Slatman f3229d3e3c
Propagate (original) request ID to webhook requests
Technically the webhook request is a new request, so maybe the
`X-Request-ID` should not be set to the value of the original
request? But then the original request ID should be propageted
in the webhook request body, or using a different header.

The way the request ID is used in this functionality is actually
more like a tracing ID, so that may be an option too.
9 months ago
Herman Slatman ea7c508fbb
Upgrade to `go.step.sm/crypto` v0.35.1 9 months ago
Herman Slatman c3572281ad
Upgrade `github.com/smallstep/go-attestation` to fix legacy `tpm2` 9 months ago
Herman Slatman f2993c4c3b
Use the legacy `tpm2` package import 9 months ago
dependabot[bot] 18d1b21a66
Bump github.com/google/go-tpm from 0.3.3 to 0.9.0
Bumps [github.com/google/go-tpm](https://github.com/google/go-tpm) from 0.3.3 to 0.9.0.
- [Release notes](https://github.com/google/go-tpm/releases)
- [Commits](https://github.com/google/go-tpm/compare/v0.3.3...v0.9.0)

---
updated-dependencies:
- dependency-name: github.com/google/go-tpm
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
9 months ago
github-actions[bot] 70533f55a4
Merge pull request #1538 from smallstep/dependabot/go_modules/github.com/hashicorp/vault/api/auth/kubernetes-0.5.0
Bump github.com/hashicorp/vault/api/auth/kubernetes from 0.4.1 to 0.5.0
9 months ago
github-actions[bot] b63276cc04
Merge pull request #1539 from smallstep/dependabot/go_modules/google.golang.org/api-0.141.0
Bump google.golang.org/api from 0.138.0 to 0.141.0
9 months ago
dependabot[bot] d05f030452
Bump google.golang.org/api from 0.138.0 to 0.141.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.138.0 to 0.141.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.138.0...v0.141.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
9 months ago
github-actions[bot] 1a6301e977
Merge pull request #1540 from smallstep/dependabot/go_modules/google.golang.org/grpc-1.58.1
Bump google.golang.org/grpc from 1.58.0 to 1.58.1
9 months ago
dependabot[bot] a73617150e
Bump google.golang.org/grpc from 1.58.0 to 1.58.1
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.58.0 to 1.58.1.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.58.0...v1.58.1)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
9 months ago
dependabot[bot] 75132d94f3
Bump github.com/hashicorp/vault/api/auth/kubernetes from 0.4.1 to 0.5.0
Bumps [github.com/hashicorp/vault/api/auth/kubernetes](https://github.com/hashicorp/vault) from 0.4.1 to 0.5.0.
- [Release notes](https://github.com/hashicorp/vault/releases)
- [Changelog](https://github.com/hashicorp/vault/blob/main/CHANGELOG-v0.md)
- [Commits](https://github.com/hashicorp/vault/compare/v0.4.1...v0.5.0)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/vault/api/auth/kubernetes
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
9 months ago
github-actions[bot] fda0bdb0c7
Merge pull request #1531 from smallstep/dependabot/go_modules/google.golang.org/grpc-1.58.0
Bump google.golang.org/grpc from 1.57.0 to 1.58.0
10 months ago
dependabot[bot] 77eeb7e2c5
Bump google.golang.org/grpc from 1.57.0 to 1.58.0
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.57.0 to 1.58.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.57.0...v1.58.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
10 months ago
github-actions[bot] 828591c61b
Merge pull request #1530 from smallstep/dependabot/go_modules/golang.org/x/net-0.15.0
Bump golang.org/x/net from 0.14.0 to 0.15.0
10 months ago
github-actions[bot] 1a4203edc0
Merge pull request #1533 from smallstep/dependabot/go_modules/github.com/hashicorp/vault/api/auth/approle-0.5.0
Bump github.com/hashicorp/vault/api/auth/approle from 0.4.1 to 0.5.0
10 months ago
dependabot[bot] 23cc1c71ee
Bump golang.org/x/net from 0.14.0 to 0.15.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.14.0 to 0.15.0.
- [Commits](https://github.com/golang/net/compare/v0.14.0...v0.15.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
10 months ago
github-actions[bot] fc1b720f35
Merge pull request #1532 from smallstep/dependabot/go_modules/golang.org/x/crypto-0.13.0
Bump golang.org/x/crypto from 0.12.0 to 0.13.0
10 months ago
Max 67a41dca83
Remove db datasource from error msg to prevent leaking of secrets (#1528) 10 months ago
dependabot[bot] ea40de159c
Bump github.com/hashicorp/vault/api/auth/approle from 0.4.1 to 0.5.0
Bumps [github.com/hashicorp/vault/api/auth/approle](https://github.com/hashicorp/vault) from 0.4.1 to 0.5.0.
- [Release notes](https://github.com/hashicorp/vault/releases)
- [Changelog](https://github.com/hashicorp/vault/blob/main/CHANGELOG-v0.md)
- [Commits](https://github.com/hashicorp/vault/compare/v0.4.1...v0.5.0)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/vault/api/auth/approle
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
10 months ago
dependabot[bot] b330c63df8
Bump golang.org/x/crypto from 0.12.0 to 0.13.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.12.0 to 0.13.0.
- [Commits](https://github.com/golang/crypto/compare/v0.12.0...v0.13.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
10 months ago
Max b7c4ed26fb
Use provisioner name in error message (#1524) 10 months ago
Herman Slatman 4cc4bba7e9
Merge pull request #1523 from smallstep/herman/scep-webhook-csr
Add CSR to `SCEPCHALLENGE` webhook request body
10 months ago
Herman Slatman 33e661ce7d
Add a dummy CSR to SCEP request body tests 10 months ago
Carl Tashian 09ccb22c4b
Merge pull request #1521 from smallstep/carl/winget
Winget: Only make PRs on releases, not release candidates
10 months ago
Herman Slatman 36f1dd70bf
Add CSR to `SCEPCHALLENGE` webhook request body 10 months ago
Herman Slatman 98d015b5c3
Fix linting issues 10 months ago
Herman Slatman d9f56cdbdc
Merge branch 'master' into herman/scep-provisioner-decrypter 10 months ago
Herman Slatman 9d3b78ae49
Add `excludeIntermediate` to SCEP provisioner 10 months ago
Carl Tashian db369ddc23
Only make PRs on releases, not release candidates 10 months ago
Carl Tashian 83e5d4222d
Merge pull request #1519 from smallstep/carl/winget
Add Winget release automation
10 months ago
Max e22166c628
provisionerOptionsToLinkedCA missing template and templateData (#1520) 10 months ago
Carl Tashian 73d765d1a9
Add Winget release automation 10 months ago
Max 116ff8ed65
bump go.mod to go1.20 and associated linter fixes (#1518) 10 months ago
github-actions[bot] d727f228ff
Merge pull request #1517 from smallstep/dependabot/go_modules/github.com/google/uuid-1.3.1
Bump github.com/google/uuid from 1.3.0 to 1.3.1
10 months ago
dependabot[bot] 8d26a6c832
Bump github.com/google/uuid from 1.3.0 to 1.3.1
Bumps [github.com/google/uuid](https://github.com/google/uuid) from 1.3.0 to 1.3.1.
- [Release notes](https://github.com/google/uuid/releases)
- [Changelog](https://github.com/google/uuid/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/uuid/compare/v1.3.0...v1.3.1)

---
updated-dependencies:
- dependency-name: github.com/google/uuid
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
10 months ago
github-actions[bot] ddabd453bd
Merge pull request #1513 from smallstep/dependabot/go_modules/google.golang.org/api-0.138.0
Bump google.golang.org/api from 0.136.0 to 0.138.0
10 months ago
github-actions[bot] fc0edb4c90
Merge pull request #1514 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.35.0
Bump go.step.sm/crypto from 0.34.0 to 0.35.0
10 months ago
dependabot[bot] dccbe9f845
Bump go.step.sm/crypto from 0.34.0 to 0.35.0
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.34.0 to 0.35.0.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.34.0...v0.35.0)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
10 months ago
dependabot[bot] 1ca2353160
Bump google.golang.org/api from 0.136.0 to 0.138.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.136.0 to 0.138.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.136.0...v0.138.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
10 months ago
Mariano Cano 9ea1e64a0a
Merge pull request #1511 from smallstep/fix-cbor-error
Fix error string in tests
10 months ago
Mariano Cano d739aab345
Define BaseContext before starting the server in tests
If the http.Server BaseContext is not define before the start of the
server, it might not be properly set depending on the goroutine
scheduler. This was causing random errors on CI.
10 months ago
Mariano Cano d8eeebfd51
Fix error string in tests
This commit fixes a test checking an error string from an external
dependency.
10 months ago
Mariano Cano 6067560834
Merge pull request #1510 from rvichery/aws-iid-all-certificates
Add all AWS identity document certificates
10 months ago
Remi Vichery 82b8e16d7f
Add all AWS identity document certificates
* move to use embed instead of a multi-line string
* add test to ensure all certificates are valid
* add test to ensure validity (no expired certificate)
10 months ago
github-actions[bot] d3a16ab212
Merge pull request #1506 from smallstep/dependabot/go_modules/google.golang.org/api-0.136.0
Bump google.golang.org/api from 0.134.0 to 0.136.0
11 months ago
github-actions[bot] b45127e3d5
Merge pull request #1507 from smallstep/dependabot/go_modules/github.com/newrelic/go-agent/v3-3.24.1
Bump github.com/newrelic/go-agent/v3 from 3.24.0 to 3.24.1
11 months ago
github-actions[bot] 645fdfccef
Merge pull request #1508 from smallstep/dependabot/go_modules/github.com/fxamacker/cbor/v2-2.5.0
Bump github.com/fxamacker/cbor/v2 from 2.4.0 to 2.5.0
11 months ago
dependabot[bot] b0b300988d
Bump github.com/fxamacker/cbor/v2 from 2.4.0 to 2.5.0
Bumps [github.com/fxamacker/cbor/v2](https://github.com/fxamacker/cbor) from 2.4.0 to 2.5.0.
- [Release notes](https://github.com/fxamacker/cbor/releases)
- [Commits](https://github.com/fxamacker/cbor/compare/v2.4.0...v2.5.0)

---
updated-dependencies:
- dependency-name: github.com/fxamacker/cbor/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
11 months ago
dependabot[bot] 3d7ddfdacc
Bump github.com/newrelic/go-agent/v3 from 3.24.0 to 3.24.1
Bumps [github.com/newrelic/go-agent/v3](https://github.com/newrelic/go-agent) from 3.24.0 to 3.24.1.
- [Release notes](https://github.com/newrelic/go-agent/releases)
- [Changelog](https://github.com/newrelic/go-agent/blob/master/CHANGELOG.md)
- [Commits](https://github.com/newrelic/go-agent/compare/v3.24.0...v3.24.1)

---
updated-dependencies:
- dependency-name: github.com/newrelic/go-agent/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
11 months ago
dependabot[bot] e51e82b9f0
Bump google.golang.org/api from 0.134.0 to 0.136.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.134.0 to 0.136.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.134.0...v0.136.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
11 months ago
github-actions[bot] 12bcb64b26
Merge pull request #1505 from smallstep/dependabot/go_modules/github.com/newrelic/go-agent/v3-3.24.0
Bump github.com/newrelic/go-agent/v3 from 3.23.1 to 3.24.0
11 months ago
github-actions[bot] 4ded102f81
Merge pull request #1503 from smallstep/dependabot/go_modules/golang.org/x/net-0.14.0
Bump golang.org/x/net from 0.13.0 to 0.14.0
11 months ago
dependabot[bot] 91ef511e65
Bump github.com/newrelic/go-agent/v3 from 3.23.1 to 3.24.0
Bumps [github.com/newrelic/go-agent/v3](https://github.com/newrelic/go-agent) from 3.23.1 to 3.24.0.
- [Release notes](https://github.com/newrelic/go-agent/releases)
- [Changelog](https://github.com/newrelic/go-agent/blob/master/CHANGELOG.md)
- [Commits](https://github.com/newrelic/go-agent/compare/v3.23.1...v3.24.0)

---
updated-dependencies:
- dependency-name: github.com/newrelic/go-agent/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
11 months ago
dependabot[bot] e074b77243
Bump golang.org/x/net from 0.13.0 to 0.14.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.13.0 to 0.14.0.
- [Commits](https://github.com/golang/net/compare/v0.13.0...v0.14.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
11 months ago
Herman Slatman e182c620c8
Merge branch 'master' into herman/scep-provisioner-decrypter 11 months ago
Herman Slatman 645b6ffc18
Ensure no prompt is fired for loading provisioner decrypter 11 months ago
Herman Slatman 6de964f13a
Merge pull request #1495 from smallstep/herman/acme-attestation-errors
Return more detailed errors to ACME clients using `device-attest-01`
11 months ago
Mariano Cano bdc7b1b691
Merge pull request #1501 from smallstep/safe-save
Write configuration only if encoding succeeds
11 months ago
Herman Slatman 0d09f3e202
Prevent data races with multiple PKCS7 encryption operations 11 months ago
Herman Slatman cbc1be310d
Merge branch 'master' into herman/acme-attestation-errors 11 months ago
Herman Slatman c952e9fc9d
Use `NewDetailedError` instead 11 months ago
Mariano Cano 30ce9e65f7
Write configuration only if encoding succeeds
This commit fixes a problem when the ca.json is truncated if the
encoding of the configuration fails. This can happen by adding a new
provisioner with bad template data.

Related to smallstep/cli#994
11 months ago
Herman Slatman e2e9bf5494
Clarify some SCEP properties 11 months ago
Herman Slatman 70626b157d
Merge branch 'master' into herman/scep-provisioner-decrypter 11 months ago
Mariano Cano 47d820561f
Merge pull request #1500 from smallstep/upgrade-crypto
Fix adding certificate templates with ASN.1 functions
11 months ago
Mariano Cano 4667060df8
Upgrade golang.org/x/net
This commit fixes the vulnerability GO-2023-1988, improper rendering of
text nodes in golang.org/x/net/html.

More info: https://pkg.go.dev/vuln/GO-2023-1988
11 months ago
Mariano Cano 103b4e1cf1
Fix adding certificate templates with ASN.1 functions
This commit upgrades go.step.sm/crypto with a fix to validate the
templates that use custom functions.
11 months ago
Herman Slatman 4186b2c2d0
Change JSON marshaling for SCEP provisioners
Instead of the old method that redacted sensitive information
by overriding the value of the property and changing it back
to the original, the API now uses a model specifically meant
for API responses. This prevents potential race conditions.

This may be iterated on a bit so that we don't need to rely
on the [provisioner.Interface] interface, which requires the
API model to implement unnecessary methods.
11 months ago
Herman Slatman d754000a68
Fix SCEP provisioner API test 11 months ago
Herman Slatman c0a1837cd9
Verify full decrypter/signer configuration at usage time
When changing the SCEP configuration it is possible that one
or both of the decrypter configurations required are not available
or have been provided in a way that's not usable for actual SCEP
requests.

Instead of failing hard when provisioners are loaded,
which could result in the CA not starting properly, this type of
problematic configuration errors will now be handled at usage
time instead.
11 months ago
Herman Slatman 88ed900dc3
Rely on the latest linkedca 11 months ago
Herman Slatman 0f35bb1af5
Defer missing decrypter/signer configuration errors to SCEP authority 11 months ago
Herman Slatman afdd8d3786
Upgrade `golang.org/x/net` to `v0.13.0` 11 months ago
Herman Slatman f3c24fe875
Change how multiple identifiers are printed in errors 11 months ago
Herman Slatman 4496830859
Merge branch 'master' into herman/acme-attestation-errors 11 months ago
Herman Slatman fc1fb51854
Improve SCEP authority initialization and reload 11 months ago
Herman Slatman 7163c4f95f
Add helper for getting the appropriate SCEP response signer 11 months ago
Herman Slatman 59b7419dcf
Rely on latest `linkedca` commit with `SCEPDecrypter` support 11 months ago
Herman Slatman 569a1be12c
Merge branch 'master' into herman/scep-provisioner-decrypter 11 months ago
github-actions[bot] c07124e374
Merge pull request #1499 from smallstep/dependabot/go_modules/google.golang.org/api-0.134.0
Bump google.golang.org/api from 0.132.0 to 0.134.0
11 months ago
dependabot[bot] 74240092e9
Bump google.golang.org/api from 0.132.0 to 0.134.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.132.0 to 0.134.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.132.0...v0.134.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
11 months ago
github-actions[bot] edd718d89e
Merge pull request #1498 from smallstep/dependabot/go_modules/google.golang.org/grpc-1.57.0
Bump google.golang.org/grpc from 1.56.2 to 1.57.0
11 months ago
dependabot[bot] a8b67cd9e6
Bump google.golang.org/grpc from 1.56.2 to 1.57.0
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.56.2 to 1.57.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.56.2...v1.57.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
11 months ago
Herman Slatman a0cdad335d
Add test for `WithAdditionalErrorDetail` 11 months ago
Herman Slatman 9a52675865
Return descriptive error when using unsupported format 11 months ago
Herman Slatman 0d3338ff3a
Return consistent ACME error types for specific cases 11 months ago
Herman Slatman df22b8a303
Cleanup some leftover TODOs 11 months ago
Mariano Cano d8a9c69eaa
Merge pull request #1484 from smallstep/fix-620
Add support for the disableSmallstepExtensions claim
11 months ago
Herman Slatman dd9bf1e915
Add error details for the `step` format 11 months ago
Herman Slatman 9cbbd1d575
Add error details to ACME `tpm` format validation errors 11 months ago
Herman Slatman d5dd8feccd
Prevent internal errors from being returned to ACME clients 11 months ago
Herman Slatman 979e0f8f51
Add error details to select error cases for `apple` format 11 months ago
Mariano Cano d0fd9ebe42
Update Makefile preparing for a new release 11 months ago
Mariano Cano cce7d9e839
Address comments from code review 11 months ago
Mariano Cano c7c7decd5e
Add support for the disableSmallstepExtensions claim
This commit adds a new claim to exclude the Smallstep provisioner
extension from the generated certificates.

Fixes #620
11 months ago
Mariano Cano d7efceadb1
Merge pull request #1493 from smallstep/steppath
Remove automatic initialization of the STEPPATH
11 months ago
Mariano Cano 7429008599
Use tagged versions of crypto and cli-utils 11 months ago
Herman Slatman 1ce80cf740
Merge branch 'master' into herman/scep-provisioner-decrypter 11 months ago
Herman Slatman 567fc25404
Use the RSA decryption configuration for signing responses too 11 months ago
Mariano Cano 7061147885
Use step.Abs to load the certificate templates
step.Abs has been removed from crypto and they need to be set when those
methods are used
11 months ago
Mariano Cano 40a2f53589
Remove automatic initialization of the STEPPATH
This commit upgrades cli-utils and crypto packages that remove the
automatic initialization of the STEPPATH.
11 months ago
Herman Slatman 557672bb4b
Add some notes for SCEP provisioners 11 months ago
Mariano Cano 95887ebf40
Merge pull request #1481 from smallstep/remove-user-regex
Remove OIDC user regexp check
11 months ago
Josh Drake a1350b14fb
Merge pull request #1489 from smallstep/josh/authorization-principal-in-webhook
Include authorization principal in provisioner webhooks.
11 months ago
Mariano Cano c9df65ebae
Merge pull request #1490 from smallstep/dry-run-migration
Add option to dry-run the migration
11 months ago
Mariano Cano d9d7c52997
Add option to dry-run the migration
This commit adds an option that runs the migration on a virtual database
that doesn't do anything. This option can be used to see how many rows
there are.
11 months ago
Josh Drake ff424fa944
Fix tests. 11 months ago
github-actions[bot] 7282245e88
Merge pull request #1488 from smallstep/dependabot/go_modules/go.step.sm/linkedca-0.20.0
Bump go.step.sm/linkedca from 0.19.1 to 0.20.0
11 months ago
github-actions[bot] 9a7582d1d3
Merge pull request #1487 from smallstep/dependabot/go_modules/google.golang.org/api-0.132.0
Bump google.golang.org/api from 0.131.0 to 0.132.0
11 months ago
dependabot[bot] 7796ad8f90
Bump go.step.sm/linkedca from 0.19.1 to 0.20.0
Bumps [go.step.sm/linkedca](https://github.com/smallstep/linkedca) from 0.19.1 to 0.20.0.
- [Release notes](https://github.com/smallstep/linkedca/releases)
- [Commits](https://github.com/smallstep/linkedca/compare/v0.19.1...v0.20.0)

---
updated-dependencies:
- dependency-name: go.step.sm/linkedca
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
11 months ago
dependabot[bot] 2d666cfc4f
Bump google.golang.org/api from 0.131.0 to 0.132.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.131.0 to 0.132.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.131.0...v0.132.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
11 months ago
Josh Drake 904f416d20
Include authorization principal in provisioner webhooks. 11 months ago
Mariano Cano d89c3a942e
Merge pull request #1486 from smallstep/migrate-admindb
Add to the migration script the admin tables
11 months ago
Mariano Cano aa30c2c73c
Add to the migration script the admin tables 11 months ago
Mariano Cano 31533c4a15
Merge pull request #1485 from smallstep/webhooks-x5c
Send X5C leaf certificate to webhooks
11 months ago
Mariano Cano 5bfe96d8c7
Send X5C leaf certificate to webhooks
This commit adds a new property that will be sent to authorizing and
enriching webhooks when signing certificates using the X5C provisioner.
11 months ago
Mariano Cano d604a900ed
Merge pull request #1482 from smallstep/fix-reload-tests
Wait for Accept in TestBootstrapClientServerRotation
11 months ago
Mariano Cano 0c3a1aea38
Wait for Accept in TestBootstrapClientServerRotation
The TestBootstrapClientServerRotation often fails because the reload
returns once the Server loop gets the new listener, but the server
hasn't really started yet. This commit makes the test pass, adding a
small sleep after the reload.

A proper fix might require a wrapper over the listener and an ACK
callback on a sync.Once on a custom Accept.
11 months ago
Mariano Cano 7fa97bedec
Remove OIDC user regexp check
This commit removes the regular expression check on OIDC usernames.
Although it is not recommended to use any character in a username,
it is possible to create and use them. The tool useradd has the flag
--badname and adduser has --allow-badname and --allow-all-names to
create new users with any character.

Moreover, it is possible to create any username with the rest of
provisioners.

Fixes #1436
11 months ago
Mariano Cano cbc46d11e5
Merge pull request #1477 from smallstep/badger-migration
Add tool to migrate data from badger to mysql or postgresql
11 months ago
Mariano Cano 1755c8d60f
Fix typo in comment 11 months ago
Mariano Cano f7da9a6f30
Allow to resume badger migration using a given key 11 months ago
Mariano Cano f7c33d0878
Fix typos in badger migration script 11 months ago
Mariano Cano 7bca0c2349
Add tool to migrate data from badger to mysql or postgresql 11 months ago
Mariano Cano 90bac46a00
Merge pull request #1476 from smallstep/fix-1463
Upgrade go.step.sm/crypto with yubikey fix
11 months ago
Mariano Cano 9edf43b188
Upgrade go.step.sm/crypto with yubikey fix
This commit upgrades the go.step.sm/crypto with a version that includes
a mutex on YubiKey sign and decrypt operations.

Fixes #1463
11 months ago
github-actions[bot] f998b19bb3
Merge pull request #1474 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.32.3
Bump go.step.sm/crypto from 0.32.2 to 0.32.3
11 months ago
github-actions[bot] 41ff437a6b
Merge pull request #1475 from smallstep/dependabot/go_modules/google.golang.org/api-0.131.0
Bump google.golang.org/api from 0.130.0 to 0.131.0
11 months ago
dependabot[bot] d1607e460d
Bump google.golang.org/api from 0.130.0 to 0.131.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.130.0 to 0.131.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.130.0...v0.131.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
11 months ago
dependabot[bot] b9a3031b84
Bump go.step.sm/crypto from 0.32.2 to 0.32.3
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.32.2 to 0.32.3.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.32.2...v0.32.3)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
11 months ago
Carl Tashian 4059184b43
Merge pull request #1446 from smallstep/carl/check-cgo-deps
Address Makefile issues around the cgo build
12 months ago
Herman Slatman 0607027412
Merge branch 'master' into carl/check-cgo-deps 12 months ago
Herman Slatman d39a28535d
Merge pull request #1462 from testwill/ioutil
chore: log error
12 months ago
github-actions[bot] a6c6df9283
Merge pull request #1469 from smallstep/dependabot/go_modules/github.com/googleapis/gax-go/v2-2.12.0
Bump github.com/googleapis/gax-go/v2 from 2.11.0 to 2.12.0
12 months ago
dependabot[bot] a6dd12675c
Bump github.com/googleapis/gax-go/v2 from 2.11.0 to 2.12.0
Bumps [github.com/googleapis/gax-go/v2](https://github.com/googleapis/gax-go) from 2.11.0 to 2.12.0.
- [Release notes](https://github.com/googleapis/gax-go/releases)
- [Commits](https://github.com/googleapis/gax-go/compare/v2.11.0...v2.12.0)

---
updated-dependencies:
- dependency-name: github.com/googleapis/gax-go/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
12 months ago
github-actions[bot] e1db416c7d
Merge pull request #1470 from smallstep/dependabot/go_modules/google.golang.org/api-0.130.0
Bump google.golang.org/api from 0.129.0 to 0.130.0
12 months ago
dependabot[bot] 2b3bf88001
Bump google.golang.org/api from 0.129.0 to 0.130.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.129.0 to 0.130.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.129.0...v0.130.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
12 months ago
github-actions[bot] df20d8fcb4
Merge pull request #1468 from smallstep/dependabot/go_modules/google.golang.org/grpc-1.56.2
Bump google.golang.org/grpc from 1.56.1 to 1.56.2
12 months ago
dependabot[bot] 49d1ca0a49
Bump google.golang.org/grpc from 1.56.1 to 1.56.2
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.56.1 to 1.56.2.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.56.1...v1.56.2)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
12 months ago
github-actions[bot] 0723987573
Merge pull request #1466 from smallstep/dependabot/go_modules/golang.org/x/net-0.12.0
Bump golang.org/x/net from 0.11.0 to 0.12.0
12 months ago
dependabot[bot] ef0cd093e3
Bump golang.org/x/net from 0.11.0 to 0.12.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.11.0 to 0.12.0.
- [Commits](https://github.com/golang/net/compare/v0.11.0...v0.12.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
12 months ago
Herman Slatman 10b7280e17
Merge pull request #1464 from smallstep/herman/fix-tpm-simulator-tests
Fix TPM simulator initialization for tests
12 months ago
Herman Slatman a5801b3c74
Fix TPM simulator initialization for tests 12 months ago
Carl Tashian 18bc0f333b
Update README.md
Co-authored-by: Herman Slatman <hslatman@users.noreply.github.com>
12 months ago
Carl Tashian 44f3b97e61
Update Makefile
Co-authored-by: Herman Slatman <hslatman@users.noreply.github.com>
12 months ago
guoguangwu 4c70abcd62 chore: log error 12 months ago
github-actions[bot] 9a60734504
Merge pull request #1458 from smallstep/dependabot/go_modules/google.golang.org/api-0.129.0
Bump google.golang.org/api from 0.128.0 to 0.129.0
12 months ago
github-actions[bot] dc03edbc27
Merge pull request #1460 from smallstep/dependabot/go_modules/github.com/newrelic/go-agent/v3-3.23.1
Bump github.com/newrelic/go-agent/v3 from 3.23.0 to 3.23.1
12 months ago
dependabot[bot] 9cb2c4365d
Bump google.golang.org/api from 0.128.0 to 0.129.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.128.0 to 0.129.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.128.0...v0.129.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
12 months ago
github-actions[bot] 03011660a8
Merge pull request #1459 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.32.2
Bump go.step.sm/crypto from 0.32.1 to 0.32.2
12 months ago
github-actions[bot] 701a0ea3f4
Merge pull request #1456 from smallstep/dependabot/go_modules/cloud.google.com/go/longrunning-0.5.1
Bump cloud.google.com/go/longrunning from 0.5.0 to 0.5.1
12 months ago
github-actions[bot] 62212d23bf
Merge pull request #1457 from smallstep/dependabot/go_modules/google.golang.org/grpc-1.56.1
Bump google.golang.org/grpc from 1.56.0 to 1.56.1
12 months ago
dependabot[bot] eae423ed14
Bump github.com/newrelic/go-agent/v3 from 3.23.0 to 3.23.1
Bumps [github.com/newrelic/go-agent/v3](https://github.com/newrelic/go-agent) from 3.23.0 to 3.23.1.
- [Release notes](https://github.com/newrelic/go-agent/releases)
- [Changelog](https://github.com/newrelic/go-agent/blob/master/CHANGELOG.md)
- [Commits](https://github.com/newrelic/go-agent/compare/v3.23.0...v3.23.1)

---
updated-dependencies:
- dependency-name: github.com/newrelic/go-agent/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
12 months ago
dependabot[bot] d59b16cb2a
Bump go.step.sm/crypto from 0.32.1 to 0.32.2
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.32.1 to 0.32.2.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.32.1...v0.32.2)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
12 months ago
dependabot[bot] f7f66ad3ed
Bump google.golang.org/grpc from 1.56.0 to 1.56.1
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.56.0 to 1.56.1.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.56.0...v1.56.1)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
12 months ago
dependabot[bot] 898bd6a0f4
Bump cloud.google.com/go/longrunning from 0.5.0 to 0.5.1
Bumps [cloud.google.com/go/longrunning](https://github.com/googleapis/google-cloud-go) from 0.5.0 to 0.5.1.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/v0.5.0...dataflow/v0.5.1)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/longrunning
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
12 months ago
github-actions[bot] 4f21d0c256
Merge pull request #1453 from smallstep/dependabot/go_modules/github.com/newrelic/go-agent/v3-3.23.0
Bump github.com/newrelic/go-agent/v3 from 3.22.1 to 3.23.0
1 year ago
dependabot[bot] e5c46d4264
Bump github.com/newrelic/go-agent/v3 from 3.22.1 to 3.23.0
Bumps [github.com/newrelic/go-agent/v3](https://github.com/newrelic/go-agent) from 3.22.1 to 3.23.0.
- [Release notes](https://github.com/newrelic/go-agent/releases)
- [Changelog](https://github.com/newrelic/go-agent/blob/master/CHANGELOG.md)
- [Commits](https://github.com/newrelic/go-agent/compare/v3.22.1...v3.23.0)

---
updated-dependencies:
- dependency-name: github.com/newrelic/go-agent/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
github-actions[bot] 4ce88e579e
Merge pull request #1451 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.32.1
Bump go.step.sm/crypto from 0.32.0 to 0.32.1
1 year ago
dependabot[bot] 48855080ff
Bump go.step.sm/crypto from 0.32.0 to 0.32.1
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.32.0 to 0.32.1.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.32.0...v0.32.1)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
github-actions[bot] b029359e78
Merge pull request #1450 from smallstep/dependabot/go_modules/google.golang.org/protobuf-1.31.0
Bump google.golang.org/protobuf from 1.30.0 to 1.31.0
1 year ago
github-actions[bot] a577ee9699
Merge pull request #1449 from smallstep/dependabot/go_modules/cloud.google.com/go/security-1.15.1
Bump cloud.google.com/go/security from 1.15.0 to 1.15.1
1 year ago
dependabot[bot] fb7b299110
Bump google.golang.org/protobuf from 1.30.0 to 1.31.0
Bumps google.golang.org/protobuf from 1.30.0 to 1.31.0.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] ce89c09031
Bump cloud.google.com/go/security from 1.15.0 to 1.15.1
Bumps [cloud.google.com/go/security](https://github.com/googleapis/google-cloud-go) from 1.15.0 to 1.15.1.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/documentai/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/video/v1.15.0...speech/v1.15.1)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/security
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Carl Tashian e38e632dca
Post-review fixes 1 year ago
Carl Tashian f8b318bb90
Post-review fixes 1 year ago
Carl Tashian 73cb04318a
Trying a different approach 1 year ago
Carl Tashian b2b8b48949
Trying a different approach 1 year ago
Carl Tashian de52aee9b1
Trying a different approach 1 year ago
Carl Tashian 5e68a6d49a
Check for gcc and pkg-config before building with cgo enabled 1 year ago
github-actions[bot] 1df9419212
Merge pull request #1440 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.32.0
Bump go.step.sm/crypto from 0.31.2 to 0.32.0
1 year ago
github-actions[bot] f7d1376327
Merge pull request #1441 from smallstep/dependabot/go_modules/google.golang.org/api-0.128.0
Bump google.golang.org/api from 0.126.0 to 0.128.0
1 year ago
dependabot[bot] 6c4825b149
Bump google.golang.org/api from 0.126.0 to 0.128.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.126.0 to 0.128.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.126.0...v0.128.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
github-actions[bot] 648e60ac1a
Merge pull request #1442 from smallstep/dependabot/go_modules/google.golang.org/grpc-1.56.0
Bump google.golang.org/grpc from 1.55.0 to 1.56.0
1 year ago
dependabot[bot] 6aa00b3c89
Bump google.golang.org/grpc from 1.55.0 to 1.56.0
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.55.0 to 1.56.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.55.0...v1.56.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] 81228b481f
Bump go.step.sm/crypto from 0.31.2 to 0.32.0
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.31.2 to 0.32.0.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.31.2...v0.32.0)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
github-actions[bot] f4cee836bf
Merge pull request #1443 from smallstep/dependabot/go_modules/golang.org/x/net-0.11.0
Bump golang.org/x/net from 0.10.0 to 0.11.0
1 year ago
github-actions[bot] 83fc176a87
Merge pull request #1444 from smallstep/dependabot/go_modules/golang.org/x/crypto-0.10.0
Bump golang.org/x/crypto from 0.9.0 to 0.10.0
1 year ago
dependabot[bot] c74bab5161
Bump golang.org/x/crypto from 0.9.0 to 0.10.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.9.0 to 0.10.0.
- [Commits](https://github.com/golang/crypto/compare/v0.9.0...v0.10.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] d78c9f831b
Bump golang.org/x/net from 0.10.0 to 0.11.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.10.0 to 0.11.0.
- [Commits](https://github.com/golang/net/compare/v0.10.0...v0.11.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Carl Tashian 05d6f81ee9
Merge pull request #1435 from smallstep/unversioned-releases
Add unversioned filenames to GitHub assets
1 year ago
Carl Tashian eeb912e025
Add unversioned filenames to GitHub assets 1 year ago
Max 67d32685c7
[action] updated goCI workflow API (#1429) 1 year ago
github-actions[bot] 56a2a17ff8
Merge pull request #1432 from smallstep/dependabot/go_modules/github.com/newrelic/go-agent/v3-3.22.1
Bump github.com/newrelic/go-agent/v3 from 3.21.1 to 3.22.1
1 year ago
github-actions[bot] a3301bf65b
Merge pull request #1433 from smallstep/dependabot/go_modules/cloud.google.com/go/security-1.15.0
Bump cloud.google.com/go/security from 1.14.1 to 1.15.0
1 year ago
dependabot[bot] e400294238
Bump github.com/newrelic/go-agent/v3 from 3.21.1 to 3.22.1
Bumps [github.com/newrelic/go-agent/v3](https://github.com/newrelic/go-agent) from 3.21.1 to 3.22.1.
- [Release notes](https://github.com/newrelic/go-agent/releases)
- [Changelog](https://github.com/newrelic/go-agent/blob/master/CHANGELOG.md)
- [Commits](https://github.com/newrelic/go-agent/compare/v3.21.1...v3.22.1)

---
updated-dependencies:
- dependency-name: github.com/newrelic/go-agent/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
github-actions[bot] c02d4adcca
Merge pull request #1431 from smallstep/dependabot/go_modules/google.golang.org/api-0.126.0
Bump google.golang.org/api from 0.125.0 to 0.126.0
1 year ago
github-actions[bot] 02d4657ee6
Merge pull request #1434 from smallstep/dependabot/go_modules/github.com/urfave/cli-1.22.14
Bump github.com/urfave/cli from 1.22.13 to 1.22.14
1 year ago
github-actions[bot] 4bd89a8e5f
Merge pull request #1430 from smallstep/dependabot/go_modules/github.com/sirupsen/logrus-1.9.3
Bump github.com/sirupsen/logrus from 1.9.2 to 1.9.3
1 year ago
dependabot[bot] d97b254a1d
Bump github.com/urfave/cli from 1.22.13 to 1.22.14
Bumps [github.com/urfave/cli](https://github.com/urfave/cli) from 1.22.13 to 1.22.14.
- [Release notes](https://github.com/urfave/cli/releases)
- [Changelog](https://github.com/urfave/cli/blob/main/docs/CHANGELOG.md)
- [Commits](https://github.com/urfave/cli/compare/v1.22.13...v1.22.14)

---
updated-dependencies:
- dependency-name: github.com/urfave/cli
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] f3555ee0e7
Bump cloud.google.com/go/security from 1.14.1 to 1.15.0
Bumps [cloud.google.com/go/security](https://github.com/googleapis/google-cloud-go) from 1.14.1 to 1.15.0.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/documentai/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/speech/v1.14.1...video/v1.15.0)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/security
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] 3d29316d0b
Bump google.golang.org/api from 0.125.0 to 0.126.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.125.0 to 0.126.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.125.0...v0.126.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] 7ac0e4d21d
Bump github.com/sirupsen/logrus from 1.9.2 to 1.9.3
Bumps [github.com/sirupsen/logrus](https://github.com/sirupsen/logrus) from 1.9.2 to 1.9.3.
- [Release notes](https://github.com/sirupsen/logrus/releases)
- [Changelog](https://github.com/sirupsen/logrus/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sirupsen/logrus/compare/v1.9.2...v1.9.3)

---
updated-dependencies:
- dependency-name: github.com/sirupsen/logrus
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Max 53c7774d3c
[action] use common goreleaser workflow (#1427) 1 year ago
Max 825c5dd754
Update changelog for ACME kid / provisioner name change (#1426) 1 year ago
Mariano Cano ccb248394b
Merge pull request #1424 from spieglt/vault-namespaces
Add namespace field to VaultCAS JSON config
1 year ago
Theron 9d7dff6995 Add namespace field to VaultCAS JSON config 1 year ago
Max 7731edd816
Store and verify Acme account location (#1386)
* Store and verify account location on acme requests

Co-authored-by: Herman Slatman <hslatman@users.noreply.github.com>
Co-authored-by: Mariano Cano <mariano@smallstep.com>
1 year ago
github-actions[bot] cbbc54e980
Merge pull request #1417 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.31.2
Bump go.step.sm/crypto from 0.31.0 to 0.31.2
1 year ago
dependabot[bot] e5bd90918d
Bump go.step.sm/crypto from 0.31.0 to 0.31.2
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.31.0 to 0.31.2.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.31.0...v0.31.2)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
github-actions[bot] 20c05ed592
Merge pull request #1419 from smallstep/dependabot/go_modules/cloud.google.com/go/longrunning-0.5.0
Bump cloud.google.com/go/longrunning from 0.4.2 to 0.5.0
1 year ago
github-actions[bot] 1fe8b70190
Merge pull request #1416 from smallstep/dependabot/go_modules/github.com/stretchr/testify-1.8.4
Bump github.com/stretchr/testify from 1.8.3 to 1.8.4
1 year ago
dependabot[bot] 561328de05
Bump cloud.google.com/go/longrunning from 0.4.2 to 0.5.0
Bumps [cloud.google.com/go/longrunning](https://github.com/googleapis/google-cloud-go) from 0.4.2 to 0.5.0.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/longrunning/v0.4.2...v0.5.0)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/longrunning
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] 8e22402190
Bump github.com/stretchr/testify from 1.8.3 to 1.8.4
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.3 to 1.8.4.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.8.3...v1.8.4)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Herman Slatman b2bf2c330b
Simplify SCEP provisioner context handling 1 year ago
Herman Slatman 8fc3a46387
Refactor the SCEP authority initialization
Instead of relying on an intermediate `scep.Service` struct,
initialize the `scep.Authority` directly. This removes one redundant
layer of indirection.
1 year ago
Herman Slatman 6985b4be62
Clean up the SCEP authority and provisioner 1 year ago
Herman Slatman a1f187e3df
Merge branch 'master' into herman/scep-provisioner-decrypter 1 year ago
Herman Slatman 180162bd6a
Refactor SCEP provisioner and decrypter 1 year ago
github-actions[bot] ff40459035
Merge pull request #1409 from smallstep/dependabot/go_modules/github.com/hashicorp/vault/api/auth/kubernetes-0.4.1
Bump github.com/hashicorp/vault/api/auth/kubernetes from 0.4.0 to 0.4.1
1 year ago
dependabot[bot] f38ea204d1
Bump github.com/hashicorp/vault/api/auth/kubernetes from 0.4.0 to 0.4.1
Bumps [github.com/hashicorp/vault/api/auth/kubernetes](https://github.com/hashicorp/vault) from 0.4.0 to 0.4.1.
- [Release notes](https://github.com/hashicorp/vault/releases)
- [Changelog](https://github.com/hashicorp/vault/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/vault/compare/v0.4.0...v0.4.1)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/vault/api/auth/kubernetes
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
github-actions[bot] 5d069f6b94
Merge pull request #1411 from smallstep/dependabot/go_modules/github.com/googleapis/gax-go/v2-2.9.1
Bump github.com/googleapis/gax-go/v2 from 2.8.0 to 2.9.1
1 year ago
dependabot[bot] bee6bf7069
Bump github.com/googleapis/gax-go/v2 from 2.8.0 to 2.9.1
Bumps [github.com/googleapis/gax-go/v2](https://github.com/googleapis/gax-go) from 2.8.0 to 2.9.1.
- [Release notes](https://github.com/googleapis/gax-go/releases)
- [Commits](https://github.com/googleapis/gax-go/compare/v2.8.0...v2.9.1)

---
updated-dependencies:
- dependency-name: github.com/googleapis/gax-go/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
github-actions[bot] c1be2761bb
Merge pull request #1410 from smallstep/dependabot/go_modules/github.com/hashicorp/vault/api/auth/approle-0.4.1
Bump github.com/hashicorp/vault/api/auth/approle from 0.4.0 to 0.4.1
1 year ago
dependabot[bot] b4d532fd1f
Bump github.com/hashicorp/vault/api/auth/approle from 0.4.0 to 0.4.1
Bumps [github.com/hashicorp/vault/api/auth/approle](https://github.com/hashicorp/vault) from 0.4.0 to 0.4.1.
- [Release notes](https://github.com/hashicorp/vault/releases)
- [Changelog](https://github.com/hashicorp/vault/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/vault/compare/v0.4.0...v0.4.1)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/vault/api/auth/approle
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
github-actions[bot] ef839a5932
Merge pull request #1413 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.31.0
Bump go.step.sm/crypto from 0.30.0 to 0.31.0
1 year ago
dependabot[bot] 6a9241fb8e
Bump go.step.sm/crypto from 0.30.0 to 0.31.0
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.30.0 to 0.31.0.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.30.0...v0.31.0)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Herman Slatman 0377fe559b
Add basic version of provisioner specific SCEP decrypter 1 year ago
Mariano Cano 96c8cd812a
Merge pull request #1406 from smallstep/fix-1404
Fix linter errors from #1404
1 year ago
Mariano Cano 71fcdf8a0a
Fix linter errors from #1404 1 year ago
Mariano Cano fffeeec74e
Merge pull request #1404 from rnugmanov/patch-1
add AWS public certificates for me-central-1 and ap-southeast-3
1 year ago
Mariano Cano 1f0a2a8443
Merge pull request #1405 from smallstep/helm-spaces
Fix tabs instead of spaces in helm chart
1 year ago
Mariano Cano ce4fd3d514
Fix tabs instead of spaces in helm chart 1 year ago
Ruslan Nugmanov 1031324273
add AWS public certificates for me-central-1 and ap-southeast-3
As per https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/verify-signature.html
1 year ago
github-actions[bot] 101120b977
Merge pull request #1398 from smallstep/dependabot/go_modules/google.golang.org/api-0.123.0
Bump google.golang.org/api from 0.122.0 to 0.123.0
1 year ago
github-actions[bot] a477e41915
Merge pull request #1399 from smallstep/dependabot/go_modules/github.com/sirupsen/logrus-1.9.2
Bump github.com/sirupsen/logrus from 1.9.0 to 1.9.2
1 year ago
github-actions[bot] ed9a1275cd
Merge pull request #1396 from smallstep/dependabot/go_modules/github.com/stretchr/testify-1.8.3
Bump github.com/stretchr/testify from 1.8.2 to 1.8.3
1 year ago
dependabot[bot] cdf55a410b
Bump github.com/sirupsen/logrus from 1.9.0 to 1.9.2
Bumps [github.com/sirupsen/logrus](https://github.com/sirupsen/logrus) from 1.9.0 to 1.9.2.
- [Release notes](https://github.com/sirupsen/logrus/releases)
- [Changelog](https://github.com/sirupsen/logrus/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sirupsen/logrus/compare/v1.9.0...v1.9.2)

---
updated-dependencies:
- dependency-name: github.com/sirupsen/logrus
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] 19896dc04b
Bump google.golang.org/api from 0.122.0 to 0.123.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.122.0 to 0.123.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.122.0...v0.123.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] 9efc47ae42
Bump github.com/stretchr/testify from 1.8.2 to 1.8.3
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.2 to 1.8.3.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.8.2...v1.8.3)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
github-actions[bot] 4f7cdfbaa2
Merge pull request #1391 from smallstep/dependabot/go_modules/google.golang.org/api-0.122.0
Bump google.golang.org/api from 0.121.0 to 0.122.0
1 year ago
dependabot[bot] ffb6d1c0f2
Bump google.golang.org/api from 0.121.0 to 0.122.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.121.0 to 0.122.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.121.0...v0.122.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
github-actions[bot] b4d536db57
Merge pull request #1389 from smallstep/dependabot/go_modules/golang.org/x/crypto-0.9.0
Bump golang.org/x/crypto from 0.8.0 to 0.9.0
1 year ago
github-actions[bot] 57865b399b
Merge pull request #1388 from smallstep/dependabot/go_modules/cloud.google.com/go/longrunning-0.4.2
Bump cloud.google.com/go/longrunning from 0.4.1 to 0.4.2
1 year ago
Carl Tashian 96dcab88ac
Merge pull request #1394 from smallstep/carl/update-shortlinks
Update download URLs
1 year ago
Carl Tashian 5e05d6ec2e
Update download URLs 1 year ago
dependabot[bot] ca6b7049e5
Bump cloud.google.com/go/longrunning from 0.4.1 to 0.4.2
Bumps [cloud.google.com/go/longrunning](https://github.com/googleapis/google-cloud-go) from 0.4.1 to 0.4.2.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/batch/v0.4.1...longrunning/v0.4.2)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/longrunning
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
github-actions[bot] 2ef45a204f
Merge pull request #1392 from smallstep/dependabot/go_modules/cloud.google.com/go/security-1.14.1
Bump cloud.google.com/go/security from 1.14.0 to 1.14.1
1 year ago
dependabot[bot] 36cb5bf1d4
Bump cloud.google.com/go/security from 1.14.0 to 1.14.1
Bumps [cloud.google.com/go/security](https://github.com/googleapis/google-cloud-go) from 1.14.0 to 1.14.1.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/documentai/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/video/v1.14.0...speech/v1.14.1)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/security
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] f06d22a138
Bump golang.org/x/crypto from 0.8.0 to 0.9.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.8.0 to 0.9.0.
- [Commits](https://github.com/golang/crypto/compare/v0.8.0...v0.9.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Herman Slatman 6db3f5f093
Merge pull request #1385 from smallstep/update-changelog-v0.24.2
Update changelog for v0.24.2 release
1 year ago
Herman Slatman 40b69ea95c
Merge pull request #1382 from smallstep/herman/update-crypto-v0.29.4
Depend on our fork of `go-attestation`
1 year ago
Herman Slatman e71b62e95c
Merge branch 'master' into herman/update-crypto-v0.29.4 1 year ago
Herman Slatman a49ee2c03d
Add entry for `DOCKER_STEPCA_INIT_PASSWORD_FILE` 1 year ago
Herman Slatman b96831ee45
Merge pull request #1384 from francescocapuano/master
Add DOCKER_STEPCA_INIT_PASSWORD_FILE variable for Docker secrets
1 year ago
Max df13351586
Merge pull request #1381 from smallstep/max/go-1.19
Bump go.mod golang version to 1.19
1 year ago
Herman Slatman 4a60f8f71f
Add `UNRELEASED` back 1 year ago
francescocapuano 7f54153a1b Add DOCKER_STEPCA_INIT_PASSWORD_FILE variable for docker secrets
Add the management of the DOCKER_STEPCA_INIT_PASSWORD_FILE variable.  over DOCKER_STEPCA_INIT_PASSWORD.
If both are used only DOCKER_STEPCA_INIT_PASSWORD_FILE will be used.
1 year ago
Herman Slatman e52e79f745
Update changelog for v0.24.2 release 1 year ago
Herman Slatman 8abb511f64
Merge branch 'master' into herman/update-crypto-v0.29.4 1 year ago
max furman 8b256f0351
address linter warning for go 1.19 1 year ago
Mariano Cano 0b832e389d
Merge pull request #1383 from smallstep/azidentity
Upgrade go.step.sm/crypto
1 year ago
Mariano Cano 2b209b94e8
Upgrade go.step.sm/crypto with new version of azidentity 1 year ago
Herman Slatman 0c2b00f6a1
Depend on our fork of `go-attestation` 1 year ago
Herman Slatman 3c7b247712
Upgrade to `go.step.sm/crypto@v0.29.4` 1 year ago
Herman Slatman 017c3273ef
Merge pull request #1374 from smallstep/herman/log-ssh-certificate
Log SSH certificates
1 year ago
github-actions[bot] f93548df40
Merge pull request #1379 from smallstep/dependabot/go_modules/google.golang.org/api-0.121.0
Bump google.golang.org/api from 0.120.0 to 0.121.0
1 year ago
max furman 5735d1d354
Bump go.mod golang version to 1.19 1 year ago
Max 6bf7943a1b
Merge branch 'master' into dependabot/go_modules/google.golang.org/api-0.121.0 1 year ago
github-actions[bot] f4c6a72967
Merge pull request #1380 from smallstep/dependabot/go_modules/google.golang.org/grpc-1.55.0
Bump google.golang.org/grpc from 1.54.0 to 1.55.0
1 year ago
dependabot[bot] 93426d72a9
Bump google.golang.org/grpc from 1.54.0 to 1.55.0
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.54.0 to 1.55.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.54.0...v1.55.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] 570b10b8e8
Bump google.golang.org/api from 0.120.0 to 0.121.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.120.0 to 0.121.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.120.0...v0.121.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Herman Slatman f17bfdf57d
Reformat the SSH certificate logging output for read- and parsability 1 year ago
Herman Slatman 4c56877d97
Add SSH certificate logging to renew and rekey too 1 year ago
Mariano Cano 1180e33228
Merge pull request #1376 from smallstep/fix-1375
Use vaultcas ttl as a duration string
1 year ago
Mariano Cano afd5d46a90
Use vaultcas ttl as a duration string
According to docs at thttps://developer.hashicorp.com/vault/api-docs/secret/pki#ttl
the ttl can be sent as a time.Duration string.

Fixes #1375
1 year ago
Panagiotis Siatras 2139121683
optimized render.JSON (#929)
* api/render: render JSON directly to the underlying writer

* also consider json.MarshalerError a panic
1 year ago
Herman Slatman 81140f859c
Fix `valid-from` and `valid-to` times 1 year ago
Herman Slatman 39e658b527
Add test for `LogSSHCertificate` 1 year ago
Herman Slatman 922f702da3
Add logging for SSH certificate issuance 1 year ago
Herman Slatman ef951f2075
Merge pull request #1204 from smallstep/herman/improve-scep-marshaling
Improve SCEP provisioner marshaling
1 year ago
Herman Slatman 8c53dc9029
Use `require.NoError` where appropriate in provisioner tests 1 year ago
Herman Slatman 0153ff4377
Remove superfluous `GetChallengePassword` 1 year ago
Herman Slatman f9ec62f46c
Merge branch 'master' into herman/improve-scep-marshaling 1 year ago
Herman Slatman eba93da6d6
Merge pull request #1372 from smallstep/herman/crl-on-http 1 year ago
Panagiotis Siatras d797941137
do not render CRLs in memory (#1373) 1 year ago
Herman Slatman 5e35aca29c
Use `CRLConfig.IsEnabled` 1 year ago
Herman Slatman 60a4512abe
Add `/crl` and `/1.0/crl` to the insecure HTTP handler 1 year ago
Herman Slatman cb1dc8055d
Merge pull request #1366 from smallstep/herman/dynamic-scep-webhook
Dynamic SCEP challenge validation using webhooks
1 year ago
Herman Slatman c73f157ea4
Remove unused error from challenge validation controller creator 1 year ago
Herman Slatman 4f7a4f63f7
Merge branch 'master' into herman/dynamic-scep-webhook 1 year ago
Herman Slatman 4bb88adf63
Move SCEP checks after reload of provisioners in CA initialization 1 year ago
Herman Slatman e8c1e8719d
Refactor SCEP webhook validation 1 year ago
github-actions[bot] 19d72c9905
Merge pull request #1369 from smallstep/dependabot/go_modules/google.golang.org/api-0.120.0
Bump google.golang.org/api from 0.119.0 to 0.120.0
1 year ago
github-actions[bot] 3a2e60a139
Merge pull request #1370 from smallstep/dependabot/go_modules/github.com/urfave/cli-1.22.13
Bump github.com/urfave/cli from 1.22.12 to 1.22.13
1 year ago
github-actions[bot] 5ea72a2432
Merge pull request #1368 from smallstep/dependabot/go_modules/github.com/newrelic/go-agent/v3-3.21.1
Bump github.com/newrelic/go-agent/v3 from 3.21.0 to 3.21.1
1 year ago
github-actions[bot] eec7d1ee6a
Merge pull request #1371 from smallstep/dependabot/go_modules/go.step.sm/linkedca-0.19.1
Bump go.step.sm/linkedca from 0.19.0 to 0.19.1
1 year ago
dependabot[bot] 047bb6a826
Bump go.step.sm/linkedca from 0.19.0 to 0.19.1
Bumps [go.step.sm/linkedca](https://github.com/smallstep/linkedca) from 0.19.0 to 0.19.1.
- [Release notes](https://github.com/smallstep/linkedca/releases)
- [Commits](https://github.com/smallstep/linkedca/compare/v0.19.0...v0.19.1)

---
updated-dependencies:
- dependency-name: go.step.sm/linkedca
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] d19c77795e
Bump github.com/urfave/cli from 1.22.12 to 1.22.13
Bumps [github.com/urfave/cli](https://github.com/urfave/cli) from 1.22.12 to 1.22.13.
- [Release notes](https://github.com/urfave/cli/releases)
- [Changelog](https://github.com/urfave/cli/blob/main/docs/CHANGELOG.md)
- [Commits](https://github.com/urfave/cli/compare/v1.22.12...v1.22.13)

---
updated-dependencies:
- dependency-name: github.com/urfave/cli
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] 3a50a2fa28
Bump google.golang.org/api from 0.119.0 to 0.120.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.119.0 to 0.120.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.119.0...v0.120.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] bb33134f8a
Bump github.com/newrelic/go-agent/v3 from 3.21.0 to 3.21.1
Bumps [github.com/newrelic/go-agent/v3](https://github.com/newrelic/go-agent) from 3.21.0 to 3.21.1.
- [Release notes](https://github.com/newrelic/go-agent/releases)
- [Changelog](https://github.com/newrelic/go-agent/blob/master/CHANGELOG.md)
- [Commits](https://github.com/newrelic/go-agent/compare/v3.21.0...v3.21.1)

---
updated-dependencies:
- dependency-name: github.com/newrelic/go-agent/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Herman Slatman 668ff9b515
Cleanup some comments and tests 1 year ago
Herman Slatman 5f0f0f4bcc
Add SCEP webhook validation tests 1 year ago
Herman Slatman ad4d8e6c68
Add `SCEPCHALLENGE` as valid webhook type in admin API 1 year ago
Herman Slatman 419478d1e5
Make SCEP webhook validation look better 1 year ago
Herman Slatman 27cdcaf5ee
Integrate the SCEP webhook with the existing webhook logic 1 year ago
Herman Slatman 05f7ab979f
Create basic webhook for SCEP challenge validation 1 year ago
Mariano Cano 1420c762e0
Merge pull request #1362 from smallstep/fix-1358
Upgrades azure-sdk-for-go to the version used in crypto
1 year ago
Mariano Cano 26afd6c932
Upgrades azure-sdk-for-go to the version used in crypto
This PR upgrades package sdk/keyvault/azkeys to v0.10.0, the same
version used in crypto.

This package wasn't upgraded in certificates and for some reason it
causes an authentication error if a client-id/client-secret is used for
authenticating with KeyVault. Managed identities or CLI authentication
works as expected.

Fixes #1358
1 year ago
github-actions[bot] 6bc2164ea1
Merge pull request #1361 from smallstep/dependabot/go_modules/github.com/hashicorp/vault/api-1.9.1
Bump github.com/hashicorp/vault/api from 1.9.0 to 1.9.1
1 year ago
github-actions[bot] 91f51252c5
Merge pull request #1360 from smallstep/dependabot/go_modules/google.golang.org/api-0.119.0
Bump google.golang.org/api from 0.118.0 to 0.119.0
1 year ago
dependabot[bot] a56b112216
Bump github.com/hashicorp/vault/api from 1.9.0 to 1.9.1
Bumps [github.com/hashicorp/vault/api](https://github.com/hashicorp/vault) from 1.9.0 to 1.9.1.
- [Release notes](https://github.com/hashicorp/vault/releases)
- [Changelog](https://github.com/hashicorp/vault/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/vault/compare/v1.9.0...v1.9.1)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/vault/api
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] f2fda93cad
Bump google.golang.org/api from 0.118.0 to 0.119.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.118.0 to 0.119.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.118.0...v0.119.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
github-actions[bot] 4dedbf7678
Merge pull request #1356 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.29.3
Bump go.step.sm/crypto from 0.29.1 to 0.29.3
1 year ago
dependabot[bot] 74414e530b
Bump go.step.sm/crypto from 0.29.1 to 0.29.3
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.29.1 to 0.29.3.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.29.1...v0.29.3)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
github-actions[bot] a784038025
Merge pull request #1355 from smallstep/dependabot/go_modules/go.step.sm/cli-utils-0.7.6
Bump go.step.sm/cli-utils from 0.7.5 to 0.7.6
1 year ago
dependabot[bot] 9e198b0e4a
Bump go.step.sm/cli-utils from 0.7.5 to 0.7.6
Bumps [go.step.sm/cli-utils](https://github.com/smallstep/cli-utils) from 0.7.5 to 0.7.6.
- [Release notes](https://github.com/smallstep/cli-utils/releases)
- [Commits](https://github.com/smallstep/cli-utils/compare/v0.7.5...v0.7.6)

---
updated-dependencies:
- dependency-name: go.step.sm/cli-utils
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
github-actions[bot] 631b773257
Merge pull request #1354 from smallstep/dependabot/go_modules/google.golang.org/api-0.118.0
Bump google.golang.org/api from 0.116.0 to 0.118.0
1 year ago
github-actions[bot] b59a8f0a9f
Merge pull request #1353 from smallstep/dependabot/go_modules/cloud.google.com/go/security-1.14.0
Bump cloud.google.com/go/security from 1.13.0 to 1.14.0
1 year ago
github-actions[bot] 0099ec7244
Merge pull request #1352 from smallstep/dependabot/go_modules/github.com/rs/xid-1.5.0
Bump github.com/rs/xid from 1.4.0 to 1.5.0
1 year ago
dependabot[bot] 0c49d119d5
Bump google.golang.org/api from 0.116.0 to 0.118.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.116.0 to 0.118.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.116.0...v0.118.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] a7480ebe4f
Bump cloud.google.com/go/security from 1.13.0 to 1.14.0
Bumps [cloud.google.com/go/security](https://github.com/googleapis/google-cloud-go) from 1.13.0 to 1.14.0.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/documentai/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/asset/v1.13.0...video/v1.14.0)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/security
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] c2f2c7176c
Bump github.com/rs/xid from 1.4.0 to 1.5.0
Bumps [github.com/rs/xid](https://github.com/rs/xid) from 1.4.0 to 1.5.0.
- [Release notes](https://github.com/rs/xid/releases)
- [Commits](https://github.com/rs/xid/compare/v1.4.0...v1.5.0)

---
updated-dependencies:
- dependency-name: github.com/rs/xid
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Max 7ad81a6c54
Merge pull request #1348 from smallstep/max/release-error
[action] Fix docker image name in release workflow
1 year ago
Max 99f9b2fb3e
Update .github/workflows/release.yml
Co-authored-by: Mariano Cano <mariano@smallstep.com>
1 year ago
max furman 574351a8f7
[action] Fix docker image name in release workflow 1 year ago
Mariano Cano ef337f5285
Merge pull request #1347 from smallstep/v0.24.0-changelog
Add changelog for v0.24.0
1 year ago
Mariano Cano b5dbeefcc6
Add changelog for v0.24.0 1 year ago
Max 5ec9e761ca
Merge pull request #1299 from smallstep/docker-hsm-glibc
Update Dockerfile.hsm to use debian:bullseye base image
1 year ago
Carl Tashian 3665616015
Deprecate the step-ca-hsm image in favor of step-ca:hsm 1 year ago
Mariano Cano 848e44e5c8
Merge pull request #1345 from smallstep/asn1-functions
Upgrade go.step.sm/crypto with new ASN.1 functions
1 year ago
Mariano Cano b034c06ac8
Upgrade go.step.sm/crypto with new ASN.1 functions
This commit upgrades go.step.sm/crypto to v0.29.1. This version adds the
following template functions:
- asn1Enc
- asn1Marshal
- asn1Seq
- asn1Set
1 year ago
github-actions[bot] 38c715ca46
Merge pull request #1342 from smallstep/dependabot/go_modules/google.golang.org/api-0.116.0
Bump google.golang.org/api from 0.114.0 to 0.116.0
1 year ago
dependabot[bot] 4133e7d069
Bump google.golang.org/api from 0.114.0 to 0.116.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.114.0 to 0.116.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.114.0...v0.116.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
github-actions[bot] 2e1e529731
Merge pull request #1343 from smallstep/dependabot/go_modules/golang.org/x/crypto-0.8.0
Bump golang.org/x/crypto from 0.7.0 to 0.8.0
1 year ago
dependabot[bot] f3bd1d3dbd
Bump golang.org/x/crypto from 0.7.0 to 0.8.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.7.0 to 0.8.0.
- [Release notes](https://github.com/golang/crypto/releases)
- [Commits](https://github.com/golang/crypto/compare/v0.7.0...v0.8.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
github-actions[bot] 432dd7ce10
Merge pull request #1344 from smallstep/dependabot/go_modules/golang.org/x/net-0.9.0
Bump golang.org/x/net from 0.8.0 to 0.9.0
1 year ago
dependabot[bot] aeb02e280e
Bump golang.org/x/net from 0.8.0 to 0.9.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.8.0 to 0.9.0.
- [Release notes](https://github.com/golang/net/releases)
- [Commits](https://github.com/golang/net/compare/v0.8.0...v0.9.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Herman Slatman 64e39cb0c9
Merge pull request #1063 from smallstep/herman/acme-da-tpm
Add ACME DA TPM attestation
1 year ago
Herman Slatman cfd65484fc
Update to `v0.29.0` of `go.step.sm/crypto` 1 year ago
Herman Slatman d9aa2c110f
Increase test coverage for AK certificate properties 1 year ago
Carl Tashian a815039283
Merge pull request #1340 from smallstep/carl/cosign-flags-update
Update cosign usage note
1 year ago
Carl Tashian b5baa55a60
Update cosign usage note 1 year ago
Herman Slatman ed1a62206e
Add additional verification of AK certificate 1 year ago
Herman Slatman 1c38e252a6
Cast `alg` to a valid `COSEAlgorithmIdentifier` 1 year ago
Herman Slatman e25acff13c
Simplify `alg` validity check 1 year ago
Herman Slatman dfc56f21b8
Merge branch 'master' into herman/acme-da-tpm 1 year ago
Herman Slatman 9cd4b362f7
Extract the `ParseSubjectAlternativeNames` function 1 year ago
github-actions[bot] b4da554aa6
Merge pull request #1337 from smallstep/dependabot/go_modules/github.com/newrelic/go-agent/v3-3.21.0
Bump github.com/newrelic/go-agent/v3 from 3.20.4 to 3.21.0
1 year ago
dependabot[bot] 6905979537
Bump github.com/newrelic/go-agent/v3 from 3.20.4 to 3.21.0
Bumps [github.com/newrelic/go-agent/v3](https://github.com/newrelic/go-agent) from 3.20.4 to 3.21.0.
- [Release notes](https://github.com/newrelic/go-agent/releases)
- [Changelog](https://github.com/newrelic/go-agent/blob/master/CHANGELOG.md)
- [Commits](https://github.com/newrelic/go-agent/compare/v3.20.4...v3.21.0)

---
updated-dependencies:
- dependency-name: github.com/newrelic/go-agent/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Herman Slatman 827fcb6a06
Fix the `go.mod`
- Add comment to why we use fork of `github.com/google/go-attestation`
- Fix require and ordering of imports
1 year ago
Herman Slatman b6957358fc
Fix PR remarks
- Root CA error message improved
- Looping through intermediate certs
- Change checking unhandled extensions to using `if`
1 year ago
Mariano Cano 023491bcf2
Merge pull request #1336 from smallstep/pr-1051
Remove unused certificate validators and modifiers
1 year ago
Mariano Cano ac35f3489c
Remove unused certificate validators and modifiers
With the introduction of certificate templates some certificate
validators and modifiers are not used anymore. This commit deletes the
ones that are not used.
1 year ago
Herman Slatman 09bd7705cd
Fix linting issues 1 year ago
Herman Slatman f88ef6621f
Add `PermanentIdentifier` SAN parsing and tests 1 year ago
Herman Slatman 79cd42527e
Use newer version of forked `github.com/google/go-attestation` 1 year ago
Herman Slatman 52023d6083
Add tests for `doTPMAttestationFormat` 1 year ago
Mariano Cano 390acab7d0
Merge pull request #1335 from smallstep/fix-typo
Fix typo in flag usage
1 year ago
Mariano Cano 57a704f008
Fix typo in flag usage 1 year ago
Mariano Cano 21f14e5708
Merge pull request #1309 from rvichery/azure-envs-identity-token
Add identity token issuance for all Azure cloud environments
1 year ago
Herman Slatman ae30f6e96b
Add failing TPM simulator test 1 year ago
Herman Slatman 1cc3ad27a5
Run TPM simulator tests 1 year ago
Herman Slatman bf53b394a1
Add `tpm` format test with simulated TPM 1 year ago
Herman Slatman 720cafb69c
Merge branch 'master' into herman/acme-da-tpm 1 year ago
github-actions[bot] a3018d9db5
Merge pull request #1331 from smallstep/dependabot/go_modules/google.golang.org/grpc-1.54.0
Bump google.golang.org/grpc from 1.53.0 to 1.54.0
1 year ago
github-actions[bot] ca108564ff
Merge pull request #1330 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.28.0
Bump go.step.sm/crypto from 0.27.0 to 0.28.0
1 year ago
dependabot[bot] 0cb5acd01c
Bump google.golang.org/grpc from 1.53.0 to 1.54.0
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.53.0 to 1.54.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.53.0...v1.54.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] 8ed523ea67
Bump go.step.sm/crypto from 0.27.0 to 0.28.0
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.27.0 to 0.28.0.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.27.0...v0.28.0)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Remi Vichery 09cbe8ba65
fixup! Add identity token for all Azure cloud environments 1 year ago
Herman Slatman 094f0521e2
Remove check for `PermanentIdentifier` from `tpm` format validation 1 year ago
Herman Slatman f91a31f9b6
Merge branch 'master' into herman/acme-da-tpm 1 year ago
Carl Tashian df2909e712
Further docker simplifications 1 year ago
Carl Tashian 25e35aa0ad
Small dockerfile refactor 1 year ago
Carl Tashian f874e31fff
Merge pull request #1329 from smallstep/carl/make-clean
Clean up Makefile and fix goreleaser deprecation
1 year ago
Carl Tashian b92f37a61d
Use cloud tag on step-kms-plugin 1 year ago
Carl Tashian 2b76d11631
Clean up Makefile and fix goreleaser deprecation 1 year ago
github-actions[bot] 897f4711df
Merge pull request #1326 from smallstep/dependabot/go_modules/cloud.google.com/go/security-1.13.0
Bump cloud.google.com/go/security from 1.12.0 to 1.13.0
1 year ago
github-actions[bot] 1b1df26864
Merge pull request #1327 from smallstep/dependabot/go_modules/google.golang.org/protobuf-1.30.0
Bump google.golang.org/protobuf from 1.29.1 to 1.30.0
1 year ago
github-actions[bot] 92e25f0f7f
Merge pull request #1328 from smallstep/dependabot/go_modules/github.com/googleapis/gax-go/v2-2.8.0
Bump github.com/googleapis/gax-go/v2 from 2.7.1 to 2.8.0
1 year ago
dependabot[bot] 1859ed2666
Bump cloud.google.com/go/security from 1.12.0 to 1.13.0
Bumps [cloud.google.com/go/security](https://github.com/googleapis/google-cloud-go) from 1.12.0 to 1.13.0.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/documentai/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/asset/v1.12.0...video/v1.13.0)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/security
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] 1420f441d5
Bump google.golang.org/protobuf from 1.29.1 to 1.30.0
Bumps [google.golang.org/protobuf](https://github.com/protocolbuffers/protobuf-go) from 1.29.1 to 1.30.0.
- [Release notes](https://github.com/protocolbuffers/protobuf-go/releases)
- [Changelog](https://github.com/protocolbuffers/protobuf-go/blob/master/release.bash)
- [Commits](https://github.com/protocolbuffers/protobuf-go/compare/v1.29.1...v1.30.0)

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
github-actions[bot] bdd4d0004e
Merge pull request #1325 from smallstep/dependabot/go_modules/google.golang.org/api-0.114.0
Bump google.golang.org/api from 0.112.0 to 0.114.0
1 year ago
dependabot[bot] d8a2839955
Bump github.com/googleapis/gax-go/v2 from 2.7.1 to 2.8.0
Bumps [github.com/googleapis/gax-go/v2](https://github.com/googleapis/gax-go) from 2.7.1 to 2.8.0.
- [Release notes](https://github.com/googleapis/gax-go/releases)
- [Commits](https://github.com/googleapis/gax-go/compare/v2.7.1...v2.8.0)

---
updated-dependencies:
- dependency-name: github.com/googleapis/gax-go/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] e6339a3761
Bump google.golang.org/api from 0.112.0 to 0.114.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.112.0 to 0.114.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.112.0...v0.114.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Mariano Cano 6e0644beb2
Merge pull request #1323 from smallstep/upgrade-crypto
Upgrade go.step.sm/crypto to improved azurekms support
1 year ago
Mariano Cano 334bc81694
Upgrade go.step.sm/crypto to improved azurekms support
This commit upgrades go.step.sm/crypto to the latest version which
includes support for sovereign clouds and HSM keys.

Fixes #1276
1 year ago
Carl Tashian 7ad1ecf518
Merge pull request #1322 from smallstep/goreleaser-clean
Replace deprecated GoReleaser --rm-dist flag with --clean
1 year ago
Carl Tashian 7a3989e7f2
Replace deprecated GoReleaser --rm-dist flag with --clean
See d18adfb57e
1 year ago
github-actions[bot] 7b26ef72a0
Merge pull request #1320 from smallstep/dependabot/go_modules/google.golang.org/protobuf-1.29.1
Bump google.golang.org/protobuf from 1.29.0 to 1.29.1
1 year ago
dependabot[bot] 942f8bfc9f
Bump google.golang.org/protobuf from 1.29.0 to 1.29.1
Bumps [google.golang.org/protobuf](https://github.com/protocolbuffers/protobuf-go) from 1.29.0 to 1.29.1.
- [Release notes](https://github.com/protocolbuffers/protobuf-go/releases)
- [Changelog](https://github.com/protocolbuffers/protobuf-go/blob/master/release.bash)
- [Commits](https://github.com/protocolbuffers/protobuf-go/compare/v1.29.0...v1.29.1)

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Herman Slatman 589a62df74
Make validation of `tpm` format stricter 1 year ago
Herman Slatman 213b31bc2c
Simplify processing logic for unhandled critical extension 1 year ago
Herman Slatman e1c7e8f00b
Return the CSR public key fingerprint for `tpm` format 1 year ago
Herman Slatman 6297bace1a
Merge branch 'master' into herman/acme-da-tpm 1 year ago
Herman Slatman 69489480ab
Add more complete `tpm` format validation 1 year ago
github-actions[bot] b3a0769778
Merge pull request #1316 from smallstep/dependabot/go_modules/google.golang.org/api-0.112.0
Bump google.golang.org/api from 0.111.0 to 0.112.0
1 year ago
dependabot[bot] 6588efdb01
Bump google.golang.org/api from 0.111.0 to 0.112.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.111.0 to 0.112.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.111.0...v0.112.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
github-actions[bot] 19a91671a6
Merge pull request #1315 from smallstep/dependabot/go_modules/github.com/newrelic/go-agent/v3-3.20.4
Bump github.com/newrelic/go-agent/v3 from 3.20.3 to 3.20.4
1 year ago
github-actions[bot] 745c1cc130
Merge pull request #1318 from smallstep/dependabot/go_modules/github.com/googleapis/gax-go/v2-2.7.1
Bump github.com/googleapis/gax-go/v2 from 2.7.0 to 2.7.1
1 year ago
github-actions[bot] c72826a690
Merge pull request #1317 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.26.0
Bump go.step.sm/crypto from 0.25.2 to 0.26.0
1 year ago
github-actions[bot] 124b1e6273
Merge pull request #1319 from smallstep/dependabot/go_modules/google.golang.org/protobuf-1.29.0
Bump google.golang.org/protobuf from 1.28.1 to 1.29.0
1 year ago
dependabot[bot] bb3cddd6f1
Bump google.golang.org/protobuf from 1.28.1 to 1.29.0
Bumps [google.golang.org/protobuf](https://github.com/protocolbuffers/protobuf-go) from 1.28.1 to 1.29.0.
- [Release notes](https://github.com/protocolbuffers/protobuf-go/releases)
- [Changelog](https://github.com/protocolbuffers/protobuf-go/blob/master/release.bash)
- [Commits](https://github.com/protocolbuffers/protobuf-go/compare/v1.28.1...v1.29.0)

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] 5943c3955e
Bump github.com/googleapis/gax-go/v2 from 2.7.0 to 2.7.1
Bumps [github.com/googleapis/gax-go/v2](https://github.com/googleapis/gax-go) from 2.7.0 to 2.7.1.
- [Release notes](https://github.com/googleapis/gax-go/releases)
- [Commits](https://github.com/googleapis/gax-go/compare/v2.7.0...v2.7.1)

---
updated-dependencies:
- dependency-name: github.com/googleapis/gax-go/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] 8747156bcc
Bump go.step.sm/crypto from 0.25.2 to 0.26.0
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.25.2 to 0.26.0.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.25.2...v0.26.0)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] 442f2fe5f9
Bump github.com/newrelic/go-agent/v3 from 3.20.3 to 3.20.4
Bumps [github.com/newrelic/go-agent/v3](https://github.com/newrelic/go-agent) from 3.20.3 to 3.20.4.
- [Release notes](https://github.com/newrelic/go-agent/releases)
- [Changelog](https://github.com/newrelic/go-agent/blob/master/CHANGELOG.md)
- [Commits](https://github.com/newrelic/go-agent/compare/v3.20.3...v3.20.4)

---
updated-dependencies:
- dependency-name: github.com/newrelic/go-agent/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Remi Vichery b2c2eec76b
Add identity token for all Azure cloud environments
* Azure Public Cloud (default)
* Azure China Cloud
* Azure US Gov Cloud
* Azure German Cloud
1 year ago
Carl Tashian 4378300c80
Update cache before installing packages 1 year ago
github-actions[bot] b8ee206f71
Merge pull request #1305 from smallstep/dependabot/go_modules/google.golang.org/api-0.111.0
Bump google.golang.org/api from 0.110.0 to 0.111.0
1 year ago
github-actions[bot] 201be0891f
Merge pull request #1307 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.25.2
Bump go.step.sm/crypto from 0.25.0 to 0.25.2
1 year ago
Carl Tashian 79b3924322
Fix docker tags 1 year ago
dependabot[bot] dd43e9e09f
Bump google.golang.org/api from 0.110.0 to 0.111.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.110.0 to 0.111.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.110.0...v0.111.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] 152a0a2f3e
Bump go.step.sm/crypto from 0.25.0 to 0.25.2
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.25.0 to 0.25.2.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.25.0...v0.25.2)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
github-actions[bot] 4fb00940c6
Merge pull request #1308 from smallstep/dependabot/go_modules/golang.org/x/crypto-0.7.0
Bump golang.org/x/crypto from 0.6.0 to 0.7.0
1 year ago
dependabot[bot] 6452afc45c
Bump golang.org/x/crypto from 0.6.0 to 0.7.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.6.0 to 0.7.0.
- [Release notes](https://github.com/golang/crypto/releases)
- [Commits](https://github.com/golang/crypto/compare/v0.6.0...v0.7.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Herman Slatman 7c54154013
Merge pull request #1300 from smallstep/herman/pkcs7-rsa-oaep 1 year ago
Herman Slatman 702f844fa2
Add RSA-OAEP decryption support to changelog 1 year ago
Herman Slatman 4d6ecf9a48
Upgrade to latest `smallstep/pkcs7` to fix RSA OAEP decryption 1 year ago
Carl Tashian 12d8ca526a
Update Dockerfile.hsm to use debian:bullseye base image 1 year ago
Mariano Cano 2eb90bf45e
Merge pull request #1298 from smallstep/badger-gc
Add support for compacting the badger db
1 year ago
Mariano Cano 7700bb77da
Remove old call to compact 1 year ago
Mariano Cano 831a1e35ea
Add support for compating the badger db
This commit adds a job that will compact the badger db periodically.
In the nosql package, when Compact is called, it will run badger's
RunValueLogGC method.
1 year ago
github-actions[bot] f8adb0a51c
Merge pull request #1295 from smallstep/dependabot/go_modules/github.com/stretchr/testify-1.8.2
Bump github.com/stretchr/testify from 1.8.1 to 1.8.2
1 year ago
dependabot[bot] fe63f3e832
Bump github.com/stretchr/testify from 1.8.1 to 1.8.2
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.1 to 1.8.2.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.8.1...v1.8.2)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Mariano Cano 060a2f186c
Merge pull request #1294 from smallstep/fix-1292
Disable database if WithNoDB() option is passed
1 year ago
Mariano Cano 4fd9a9b92b
Disable database if WithNoDB() option is passed
This commit removes the database from the configuration if the ca was
initialized with the "--no-db" flag.

Fixes #1292
1 year ago
Mariano Cano 23423814d3
Merge pull request #1293 from LarsBingBong/patch-1
Mark the IDP critical in the generated CRL data.
1 year ago
LarsBingBong 0d5c40e059
Mark the IDP critical in the generated CRL data.
Trying to get CRL to work on my environment I've been reading up on [RFC5280](https://www.rfc-editor.org/rfc/rfc5280#section-5.2.5) ... and the IDP to be marked as `Critical`. I hope I'm correct and that my understanding on how to mark the IDP is critical.
Looking at e.g. `3470b1ec57/x509util/extensions_test.go (L48)` makes me think so.

---

Hopefully the above change - if accepted - can get CRL's to work on my environment. If not we're at least one step closer.
1 year ago
Herman Slatman 176cf30a6f
Merge pull request #1290 from smallstep/herman/email-domain-ssh-sign-error
Add email address to error message returned for OIDC validation
1 year ago
Herman Slatman 59462e826c
Improve testing errors for OIDC `authorizeToken` function 1 year ago
Herman Slatman 10958a124b
Add email address to error message returned for OIDC validation 1 year ago
github-actions[bot] b02c43cf8e
Merge pull request #1280 from smallstep/dependabot/go_modules/cloud.google.com/go/security-1.12.0
Bump cloud.google.com/go/security from 1.11.0 to 1.12.0
1 year ago
github-actions[bot] 81b1d2ede6
Merge pull request #1279 from smallstep/dependabot/go_modules/github.com/hashicorp/vault/api/auth/approle-0.4.0
Bump github.com/hashicorp/vault/api/auth/approle from 0.3.0 to 0.4.0
1 year ago
dependabot[bot] e0b9f3960c
Bump cloud.google.com/go/security from 1.11.0 to 1.12.0
Bumps [cloud.google.com/go/security](https://github.com/googleapis/google-cloud-go) from 1.11.0 to 1.12.0.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/documentai/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/asset/v1.11.0...video/v1.12.0)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/security
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] b4f8100c72
Bump github.com/hashicorp/vault/api/auth/approle from 0.3.0 to 0.4.0
Bumps [github.com/hashicorp/vault/api/auth/approle](https://github.com/hashicorp/vault) from 0.3.0 to 0.4.0.
- [Release notes](https://github.com/hashicorp/vault/releases)
- [Changelog](https://github.com/hashicorp/vault/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/vault/compare/v0.3.0...v0.4.0)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/vault/api/auth/approle
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
github-actions[bot] ae0be0acbd
Merge pull request #1282 from smallstep/dependabot/go_modules/cloud.google.com/go/longrunning-0.4.1
Bump cloud.google.com/go/longrunning from 0.4.0 to 0.4.1
1 year ago
dependabot[bot] 5f835dc808
Bump cloud.google.com/go/longrunning from 0.4.0 to 0.4.1
Bumps [cloud.google.com/go/longrunning](https://github.com/googleapis/google-cloud-go) from 0.4.0 to 0.4.1.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/v0.4.0...batch/v0.4.1)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/longrunning
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Max 6915feaae9
Merge pull request #1287 from smallstep/max/linting-errors
Fix linting errors
1 year ago
max furman 7c1c32d86b
Fix linting errors 1 year ago
github-actions[bot] 8e47f05dba
Merge pull request #1283 from smallstep/dependabot/go_modules/golang.org/x/crypto-0.6.0
Bump golang.org/x/crypto from 0.5.0 to 0.6.0
1 year ago
dependabot[bot] 790139d5a7
Bump golang.org/x/crypto from 0.5.0 to 0.6.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.5.0 to 0.6.0.
- [Release notes](https://github.com/golang/crypto/releases)
- [Commits](https://github.com/golang/crypto/compare/v0.5.0...v0.6.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Carl Tashian ca9f8dc576
Merge pull request #1278 from smallstep/policy-help
Clarify policy lockout error message
1 year ago
Carl Tashian cfcc95de93
Update policy test 1 year ago
Carl Tashian 96c6613739
Clarify policy lockout error message 1 year ago
github-actions[bot] effe729d53
Merge pull request #1267 from smallstep/dependabot/go_modules/google.golang.org/grpc-1.53.0
Bump google.golang.org/grpc from 1.52.3 to 1.53.0
1 year ago
dependabot[bot] bb068f8280
Bump google.golang.org/grpc from 1.52.3 to 1.53.0
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.52.3 to 1.53.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.52.3...v1.53.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
github-actions[bot] d59d6c414f
Merge pull request #1268 from smallstep/dependabot/go_modules/github.com/hashicorp/vault/api/auth/kubernetes-0.4.0
Bump github.com/hashicorp/vault/api/auth/kubernetes from 0.3.0 to 0.4.0
1 year ago
Max 25599f8ad5
Merge pull request #1255 from zyzyx03/fix-step-ca-path
There is an error during RA installation which shows.
1 year ago
dependabot[bot] 2f2e3dea0f
Bump github.com/hashicorp/vault/api/auth/kubernetes from 0.3.0 to 0.4.0
Bumps [github.com/hashicorp/vault/api/auth/kubernetes](https://github.com/hashicorp/vault) from 0.3.0 to 0.4.0.
- [Release notes](https://github.com/hashicorp/vault/releases)
- [Changelog](https://github.com/hashicorp/vault/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/vault/compare/v0.3.0...v0.4.0)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/vault/api/auth/kubernetes
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Mariano Cano 5fbee3d3ef
Merge pull request #1275 from smallstep/net-update
Upgrade golang.org/x/net
1 year ago
Mariano Cano 0d80473157
Upgrade golang.org/x/net
When the Go client is configured with an http2.Transport we need to
upgrade x/net due to:
  - net/http: avoid quadratic complexity in HPACK decoding (CVE-2022-41723)
1 year ago
github-actions[bot] 12d905be3e
Merge pull request #1270 from smallstep/dependabot/go_modules/golang.org/x/net-0.6.0
Bump golang.org/x/net from 0.5.0 to 0.6.0
1 year ago
dependabot[bot] 045ae52452
Bump golang.org/x/net from 0.5.0 to 0.6.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.5.0 to 0.6.0.
- [Release notes](https://github.com/golang/net/releases)
- [Commits](https://github.com/golang/net/compare/v0.5.0...v0.6.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Mariano Cano c2c246b062
Merge pull request #1265 from smallstep/check-csr-acme-da
Verify CSR key fingerprint with attestation certificate key
1 year ago
Max ff7b8830fe
Merge pull request #1273 from smallstep/max/dependabot-auto-merge
enable auto merge for dependabot PRs
1 year ago
max furman 74e6245e90
enable auto merge for dependabot PRs 1 year ago
Mariano Cano 5ff0dde819
Remove json tag in acme.Authorization fingerprint 1 year ago
Mariano Cano da95c44943
Fix lint issue with Go 1.20 1 year ago
Mariano Cano 6ba20209c2
Verify CSR key fingerprint with attestation certificate key
This commit makes sure that the attestation certificate key matches the
key used on the CSR on an ACME device attestation flow.
1 year ago
Carl Tashian ec3be2359a
Merge pull request #1262 from micheljung/patch-1
Add DOCKER_STEPCA_INIT_ADDRESS
1 year ago
Michel Jung ebe7e5d019
Add DOCKER_STEPCA_INIT_ADDRESS
This allows configuring "--address" instead of using hard-coded :9000
1 year ago
Max 03cb74a449
Merge pull request #1259 from smallstep/dependabot/go_modules/google.golang.org/api-0.109.0
Bump google.golang.org/api from 0.108.0 to 0.109.0
1 year ago
dependabot[bot] c9814be699
Bump google.golang.org/api from 0.108.0 to 0.109.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.108.0 to 0.109.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.108.0...v0.109.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
zyzyx 2c57415657 There is an error during installation which shows.
"install: cannot stat 'step-ca_0.23.2/bin/step-ca': No such file or directory"
Upon checking the is no bin directory after step-ca_linux_0.23.2_amd64.tar.gz
is extracted so by simply changing from step-ca_${CA_VERSION:1}/bin/step-ca to step-ca_${CA_VERSION:1}/step-ca the installation succeed.
1 year ago
Mariano Cano 3c76834807
Merge pull request #1254 from smallstep/changelog-v0.23.2
Add changelog for v0.23.2
1 year ago
Mariano Cano 6be15819d6
Add new entries to changelog 1 year ago
Herman Slatman da00046a61
Merge pull request #1235 from smallstep/herman/acme-da-subject-check
Improve validation and error messages for Orders with Permanent Identifier
1 year ago
Mariano Cano 2cef8d10ee
Add changelog for v0.23.2 1 year ago
Carl Tashian 067f9c9a5f
Merge pull request #1252 from smallstep/carl/startup-noconfig-msg
Helpful message on CA startup when config can't be opened
1 year ago
Herman Slatman 3a6fc5e0b4
Remove dependency on `smallstep/assert` in ACME challenge tests 1 year ago
Herman Slatman 0f1c509e4b
Remove debug utility 1 year ago
Carl Tashian b76028f3ba
Update commands/app.go
Co-authored-by: Mariano Cano <mariano@smallstep.com>
1 year ago
Carl Tashian 1c59b3f132
Fix linting error 1 year ago
Carl Tashian 50b4011b03
Move to commands/app.go 1 year ago
Mariano Cano 40538d8224
Merge pull request #1251 from smallstep/pidfile
Add pidfile flag
1 year ago
Carl Tashian 4b7fa2524d
Closes #1248 1 year ago
Mariano Cano 0df942b8f6
Add pidfile flag
This commit adds an optional flag --pidfile which allows to pass
a filename where step-ca will write its process id.

Fixes #754
1 year ago
Max 972bfb9689
Merge pull request #1250 from smallstep/max/scoop
Add scoop back to goreleaser
1 year ago
max furman e741c60afb
Add scoop back to goreleaser 1 year ago
Carl Tashian dd9b97221e
Merge pull request #1246 from smallstep/carl/fix-release-linktitle
Fixed the arch of the filename in the windows release artifact
1 year ago
Carl Tashian ed4af06a56
Fixed the arch of the filename in the windows release artifact 1 year ago
Mariano Cano 197b79bb48
Merge pull request #1243 from smallstep/remove-deprecated-binaries
Add step-kms-plugin to docker images and build a CGO based one
1 year ago
Max 0c5e7f1b5c
Merge pull request #1245 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.23.2
Bump go.step.sm/crypto from 0.23.1 to 0.23.2
1 year ago
Max d79e1343ae
Merge pull request #1244 from smallstep/dependabot/go_modules/google.golang.org/grpc-1.52.3
Bump google.golang.org/grpc from 1.52.0 to 1.52.3
1 year ago
dependabot[bot] 9a539f22fc
Bump go.step.sm/crypto from 0.23.1 to 0.23.2
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.23.1 to 0.23.2.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.23.1...v0.23.2)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] c32e84b436
Bump google.golang.org/grpc from 1.52.0 to 1.52.3
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.52.0 to 1.52.3.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.52.0...v1.52.3)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Herman Slatman 0f9128c873
Fix linting issue and order of test SUT 1 year ago
Herman Slatman 2ab9beb7ed
Add tests for `deviceAttest01Validate` 1 year ago
Mariano Cano 3b1be62663
Add step-kms-plugin to docker images and build a CGO based one 1 year ago
Herman Slatman 7c632629dd
Merge branch 'master' into herman/acme-da-subject-check 1 year ago
Herman Slatman ed61c5df5f
Cleanup some leftover debug statements 1 year ago
Herman Slatman 60a9e41c1c
Remove `Identifier` from top level ACME `Errors` 1 year ago
Herman Slatman edee01c80c
Refactor debug utility 1 year ago
Herman Slatman 1c38113e44
Add ACME `Subproblem` for more detailed ACME client-side errors
When validating an ACME challenge (`device-attest-01` in this case,
but it's also true for others), and validation fails, the CA didn't
return a lot of information about why the challenge had failed. By
introducing the ACME `Subproblem` type, an ACME `Error` can include
some additional information about what went wrong when validating
the challenge.

This is a WIP commit. The `Subproblem` isn't created in many code
paths yet, just for the `step` format at the moment. Will probably
follow up with some more improvements to how the ACME error is
handled. Also need to cleanup some debug things (q.Q)
1 year ago
Mariano Cano 4bb25d4a52
Merge pull request #1240 from smallstep/remove-deprecated-binaries
Remove deprecated binaries
1 year ago
Mariano Cano 39f46d31b9
Remove deprecated binaries
This commit removes the following deprecated binaries:

 - step-awskms-init
 - step-cloudkms-init
 - step-pkcs11-init
 - step-yubikey-init

From now on step and step-kms-plugin should be used to initialize the
PKI in AWS KMS, GCP KMS, PKCS#11 modules or YubiKeys.

A future commit will add step-kms-plugin to the docker images of
step-ca.

Fixes #1046
1 year ago
Herman Slatman f1724ea8c5
Merge branch 'master' into herman/acme-da-tpm 1 year ago
Max fc452e560c
Merge pull request #1236 from smallstep/dependabot/go_modules/github.com/newrelic/go-agent/v3-3.20.3
Bump github.com/newrelic/go-agent/v3 from 3.20.2 to 3.20.3
1 year ago
Max 4621b95f38
Merge pull request #1237 from smallstep/dependabot/go_modules/github.com/urfave/cli-1.22.12
Bump github.com/urfave/cli from 1.22.11 to 1.22.12
1 year ago
Max 2d174472e7
Merge pull request #1238 from smallstep/dependabot/go_modules/google.golang.org/api-0.108.0
Bump google.golang.org/api from 0.107.0 to 0.108.0
1 year ago
Max 3a6e90498c
Merge pull request #1239 from smallstep/dependabot/go_modules/github.com/hashicorp/vault/api-1.8.3
Bump github.com/hashicorp/vault/api from 1.8.2 to 1.8.3
1 year ago
dependabot[bot] cb8a2ee69f
Bump github.com/hashicorp/vault/api from 1.8.2 to 1.8.3
Bumps [github.com/hashicorp/vault/api](https://github.com/hashicorp/vault) from 1.8.2 to 1.8.3.
- [Release notes](https://github.com/hashicorp/vault/releases)
- [Changelog](https://github.com/hashicorp/vault/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/vault/compare/v1.8.2...v1.8.3)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/vault/api
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] 626a3a87b4
Bump google.golang.org/api from 0.107.0 to 0.108.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.107.0 to 0.108.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.107.0...v0.108.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] 925a228656
Bump github.com/urfave/cli from 1.22.11 to 1.22.12
Bumps [github.com/urfave/cli](https://github.com/urfave/cli) from 1.22.11 to 1.22.12.
- [Release notes](https://github.com/urfave/cli/releases)
- [Changelog](https://github.com/urfave/cli/blob/main/docs/CHANGELOG.md)
- [Commits](https://github.com/urfave/cli/compare/v1.22.11...v1.22.12)

---
updated-dependencies:
- dependency-name: github.com/urfave/cli
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] 07fd03c3f3
Bump github.com/newrelic/go-agent/v3 from 3.20.2 to 3.20.3
Bumps [github.com/newrelic/go-agent/v3](https://github.com/newrelic/go-agent) from 3.20.2 to 3.20.3.
- [Release notes](https://github.com/newrelic/go-agent/releases)
- [Changelog](https://github.com/newrelic/go-agent/blob/master/CHANGELOG.md)
- [Commits](https://github.com/newrelic/go-agent/compare/v3.20.2...v3.20.3)

---
updated-dependencies:
- dependency-name: github.com/newrelic/go-agent/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Herman Slatman 64d9ad7b38
Validate Subject Common Name for Orders with Permanent Identifier 1 year ago
Max 5bab65aa49
Merge pull request #1232 from smallstep/dependabot/go_modules/github.com/urfave/cli-1.22.11
Bump github.com/urfave/cli from 1.22.10 to 1.22.11
1 year ago
Max 925f32e82f
Merge pull request #1231 from smallstep/dependabot/go_modules/google.golang.org/grpc-1.52.0
Bump google.golang.org/grpc from 1.51.0 to 1.52.0
1 year ago
Max 466fe8280e
Merge pull request #1230 from smallstep/dependabot/go_modules/google.golang.org/api-0.107.0
Bump google.golang.org/api from 0.106.0 to 0.107.0
1 year ago
dependabot[bot] fb39fccf6a
Bump github.com/urfave/cli from 1.22.10 to 1.22.11
Bumps [github.com/urfave/cli](https://github.com/urfave/cli) from 1.22.10 to 1.22.11.
- [Release notes](https://github.com/urfave/cli/releases)
- [Changelog](https://github.com/urfave/cli/blob/main/docs/CHANGELOG.md)
- [Commits](https://github.com/urfave/cli/compare/v1.22.10...v1.22.11)

---
updated-dependencies:
- dependency-name: github.com/urfave/cli
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] 29deb4befa
Bump google.golang.org/grpc from 1.51.0 to 1.52.0
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.51.0 to 1.52.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.51.0...v1.52.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] 98cb439b41
Bump google.golang.org/api from 0.106.0 to 0.107.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.106.0 to 0.107.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.106.0...v0.107.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Carl Tashian cc6b87d1a4
Merge pull request #1228 from smallstep/carl/entrypoint-boolean-fix
Only pass --admin-subject if --remote-management is true; fix  boolean handling
1 year ago
Carl Tashian 2ab9483952
Only pass --admin-subject if --remote-management is true; fix overall boolean handling 1 year ago
Mariano Cano e4073270f3
Merge pull request #1225 from smallstep/0.23.1-changelog
Upgrade changelog for v0.23.1
1 year ago
Max 627506b519
Merge pull request #1207 from smallstep/max/admin-check
Add IsEnabled method in AdminClient for checking admin API availability
1 year ago
max furman fd921e5b26
successful isEnabled check should not return error 1 year ago
max furman 0b26698e72
Add IsEnabled method in AdminClient for checking admin API availability 1 year ago
Mariano Cano bab77f257a
Add changelog line for smallstep/certificates#1223 1 year ago
Carl Tashian a78ddc7cc5
Merge pull request #1223 from smallstep/carl/docker-pwd
Docker: Generate and use independent provisioner and private key passwords
1 year ago
Mariano Cano 2e86a392a8
Add proper PR links 1 year ago
Mariano Cano 2cd5708103
Upgrade changelog for v0.23.1 1 year ago
Mariano Cano ad8a95cc10
Merge pull request #1206 from smallstep/oidc-principals
Ignore principals validations with OIDC
1 year ago
Carl Tashian dc8b196823
Print admin username and pw after init 1 year ago
Carl Tashian 328276eaeb
Shred provisioner password 1 year ago
Carl Tashian ad5cbd9a0e
Print and delete provisioner password on setup 1 year ago
Carl Tashian a017238874
No need for PROVISIONER_PWDPATH 1 year ago
Carl Tashian 313bf2354b
Check for existance of pwdpath before copying 1 year ago
Carl Tashian 640bd0b7c7
Tabs to spaces 1 year ago
Carl Tashian c836c7ab40
Backward compatibility 1 year ago
Carl Tashian 8242895909
Update hsm dockerfile as well 1 year ago
Carl Tashian 844cfd3bad
Generate and use independent provisioner and private key passwords 1 year ago
Max ac4d5e63ab
Merge pull request #1221 from smallstep/dependabot/go_modules/google.golang.org/api-0.106.0
Bump google.golang.org/api from 0.105.0 to 0.106.0
1 year ago
Max 985a0e4858
Merge pull request #1220 from smallstep/dependabot/go_modules/golang.org/x/crypto-0.5.0
Bump golang.org/x/crypto from 0.4.0 to 0.5.0
1 year ago
Max 762ce06d84
Merge pull request #1219 from smallstep/dependabot/go_modules/cloud.google.com/go/security-1.11.0
Bump cloud.google.com/go/security from 1.10.0 to 1.11.0
1 year ago
dependabot[bot] 34dc119cf7
Bump google.golang.org/api from 0.105.0 to 0.106.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.105.0 to 0.106.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.105.0...v0.106.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Max 9cc35d1505
Merge branch 'master' into dependabot/go_modules/golang.org/x/crypto-0.5.0 1 year ago
dependabot[bot] e7a4a1f43c
Bump cloud.google.com/go/security from 1.10.0 to 1.11.0
Bumps [cloud.google.com/go/security](https://github.com/googleapis/google-cloud-go) from 1.10.0 to 1.11.0.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/documentai/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/asset/v1.10.0...asset/v1.11.0)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/security
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Max 8ba1b44cd8
Merge pull request #1218 from smallstep/dependabot/go_modules/cloud.google.com/go/longrunning-0.4.0
Bump cloud.google.com/go/longrunning from 0.3.0 to 0.4.0
1 year ago
Max a063961175
Merge pull request #1217 from smallstep/dependabot/go_modules/golang.org/x/net-0.5.0
Bump golang.org/x/net from 0.4.0 to 0.5.0
1 year ago
dependabot[bot] dae0ba9008
Bump golang.org/x/crypto from 0.4.0 to 0.5.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.4.0 to 0.5.0.
- [Release notes](https://github.com/golang/crypto/releases)
- [Commits](https://github.com/golang/crypto/compare/v0.4.0...v0.5.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] 32f4908310
Bump cloud.google.com/go/longrunning from 0.3.0 to 0.4.0
Bumps [cloud.google.com/go/longrunning](https://github.com/googleapis/google-cloud-go) from 0.3.0 to 0.4.0.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/v0.3.0...v0.4.0)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/longrunning
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] c5c07be298
Bump golang.org/x/net from 0.4.0 to 0.5.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.4.0 to 0.5.0.
- [Release notes](https://github.com/golang/net/releases)
- [Commits](https://github.com/golang/net/compare/v0.4.0...v0.5.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Herman Slatman b13b527d18
Merge pull request #1211 from smallstep/herman/ca-client-context-methods
Add `WithContext` methods to the CA client
2 years ago
Herman Slatman b5961beba9
Fix and/or ignore linting issues 2 years ago
Herman Slatman 319333f936
Add `WithContext` methods to the CA client 2 years ago
Max 85f6554c5e
Merge pull request #1210 from smallstep/dependabot/go_modules/golang.org/x/crypto-0.4.0
Bump golang.org/x/crypto from 0.3.0 to 0.4.0
2 years ago
Max 001c156b28
Merge pull request #1208 from smallstep/dependabot/go_modules/google.golang.org/api-0.105.0
Bump google.golang.org/api from 0.104.0 to 0.105.0
2 years ago
Max 407496234f
Merge pull request #1209 from smallstep/dependabot/go_modules/github.com/newrelic/go-agent/v3-3.20.2
Bump github.com/newrelic/go-agent/v3 from 3.20.1 to 3.20.2
2 years ago
dependabot[bot] 27a50d50d3
Bump golang.org/x/crypto from 0.3.0 to 0.4.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.3.0 to 0.4.0.
- [Release notes](https://github.com/golang/crypto/releases)
- [Commits](https://github.com/golang/crypto/compare/v0.3.0...v0.4.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 years ago
dependabot[bot] 75ffbae5a7
Bump github.com/newrelic/go-agent/v3 from 3.20.1 to 3.20.2
Bumps [github.com/newrelic/go-agent/v3](https://github.com/newrelic/go-agent) from 3.20.1 to 3.20.2.
- [Release notes](https://github.com/newrelic/go-agent/releases)
- [Changelog](https://github.com/newrelic/go-agent/blob/master/CHANGELOG.md)
- [Commits](https://github.com/newrelic/go-agent/compare/v3.20.1...v3.20.2)

---
updated-dependencies:
- dependency-name: github.com/newrelic/go-agent/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2 years ago
dependabot[bot] a4e64665da
Bump google.golang.org/api from 0.104.0 to 0.105.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.104.0 to 0.105.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.104.0...v0.105.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 years ago
Mariano Cano 5d87201abc
Ignore principals validations with OIDC
This commit will ignore principals validation when an OIDC provisioner
is used. When the principals in the server does not match the principals
given the validation was failing, even if the proper principals were set
by templates or webhooks. With this change OIDC will not validate the
principals and just set the default ones (name, name@example.org) plus
the ones in the templates.

This commit also includes a change in the templates to allow to pass
a provisioner to the $(step path)/ssh/config template

Related to #807
2 years ago
Herman Slatman 9007e2ef75
Merge pull request #1201 from smallstep/herman/docker-remote-management
Add env vars for enabling Remote Management and ACME provisioner
2 years ago
Max 3fb38a3c14
Merge pull request #1203 from smallstep/dependabot/go_modules/google.golang.org/api-0.104.0
Bump google.golang.org/api from 0.103.0 to 0.104.0
2 years ago
Max c2d441fbfd
Merge pull request #1198 from smallstep/dependabot/go_modules/github.com/Masterminds/sprig/v3-3.2.3
Bump github.com/Masterminds/sprig/v3 from 3.2.2 to 3.2.3
2 years ago
dependabot[bot] e07734d90d
Bump google.golang.org/api from 0.103.0 to 0.104.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.103.0 to 0.104.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.103.0...v0.104.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 years ago
dependabot[bot] 260f40c6bc
Bump github.com/Masterminds/sprig/v3 from 3.2.2 to 3.2.3
Bumps [github.com/Masterminds/sprig/v3](https://github.com/Masterminds/sprig) from 3.2.2 to 3.2.3.
- [Release notes](https://github.com/Masterminds/sprig/releases)
- [Changelog](https://github.com/Masterminds/sprig/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Masterminds/sprig/compare/v3.2.2...v3.2.3)

---
updated-dependencies:
- dependency-name: github.com/Masterminds/sprig/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2 years ago
Max f26e70cc16
Merge pull request #1202 from smallstep/dependabot/go_modules/golang.org/x/net-0.4.0
Bump golang.org/x/net from 0.2.0 to 0.4.0
2 years ago
Herman Slatman c365d8580e
Move provisioner marshaling logic to api package 2 years ago
Herman Slatman f2e1c56c6c
Improve SCEP provisioner marshaling 2 years ago
dependabot[bot] 47dad19bbc
Bump golang.org/x/net from 0.2.0 to 0.4.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.2.0 to 0.4.0.
- [Release notes](https://github.com/golang/net/releases)
- [Commits](https://github.com/golang/net/compare/v0.2.0...v0.4.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 years ago
Herman Slatman 4e3a6e67f1
Add env vars for enabling Remote Management and ACME provisioner.
A `step-ca` instance created in a container can now be initialized
with Remote Management by setting `DOCKER_STEPCA_INIT_REMOTE_MANAGEMENT`.
An ACME provisioner with default settings can be created at initialization
by setting `DOCKER_STEPCA_INIT_ACME`.
2 years ago
Mariano Cano a0423a4539
Merge pull request #1193 from smallstep/changelog
Update changelog
2 years ago
Mariano Cano c6e34f7b84
Update changelog
This commit updates the changelog with a comment about .crl.idpURL
configuration property.
2 years ago
Mariano Cano 5cce76672d
Merge pull request #1178 from foleyjohnm/adding-CRL-IDP-config
Adding crl idp config
2 years ago
Mariano Cano 002a058807
Use idpURL in json 2 years ago
Mariano Cano be4cd17b40
Add omit empty to IDPurl 2 years ago
Max 262814ac43
Merge pull request #1191 from smallstep/dependabot/go_modules/google.golang.org/grpc-1.51.0
Bump google.golang.org/grpc from 1.50.1 to 1.51.0
2 years ago
Max b655fcda21
Merge pull request #1190 from smallstep/dependabot/go_modules/github.com/newrelic/go-agent/v3-3.20.1
Bump github.com/newrelic/go-agent/v3 from 3.20.0 to 3.20.1
2 years ago
dependabot[bot] 596be4bec7
Bump google.golang.org/grpc from 1.50.1 to 1.51.0
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.50.1 to 1.51.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.50.1...v1.51.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 years ago
dependabot[bot] afc81d96d8
Bump github.com/newrelic/go-agent/v3 from 3.20.0 to 3.20.1
Bumps [github.com/newrelic/go-agent/v3](https://github.com/newrelic/go-agent) from 3.20.0 to 3.20.1.
- [Release notes](https://github.com/newrelic/go-agent/releases)
- [Changelog](https://github.com/newrelic/go-agent/blob/master/CHANGELOG.md)
- [Commits](https://github.com/newrelic/go-agent/compare/v3.20.0...v3.20.1)

---
updated-dependencies:
- dependency-name: github.com/newrelic/go-agent/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2 years ago
Herman Slatman 27a1ab640d
Merge pull request #1187 from smallstep/herman/fix-stack-trace-error-logging
Fix `StackTracedError` logging
2 years ago
Herman Slatman b8c306ebfa
Refactor tests stylistically 2 years ago
Herman Slatman 36da484604
Merge pull request #1188 from smallstep/herman/fix-stack-trace-error-logging-panos
Merge log.Error tests
2 years ago
Panagiotis Siatras 9197de3e96
api/log: removed dependency to certificates/logging 2 years ago
Panagiotis Siatras b7f4881972
merged log tests 2 years ago
Herman Slatman 27bbc3682b
Improve error log test readability 2 years ago
Herman Slatman 362be72120
Fix `StackTracedError` logging
When running with `STEPDEBUG=1`, a response with a `StackTracedError`
would result in a nil pointer error. This commit fixes the check and
adds a test case.
2 years ago
Max 8a2e49a1e3
Merge pull request #1182 from smallstep/dependabot/go_modules/google.golang.org/api-0.103.0
Bump google.golang.org/api from 0.102.0 to 0.103.0
2 years ago
dependabot[bot] 51503dabac
Bump google.golang.org/api from 0.102.0 to 0.103.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.102.0 to 0.103.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.102.0...v0.103.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 years ago
Max b9b60d50fe
Merge pull request #1183 from smallstep/dependabot/go_modules/golang.org/x/net-0.2.0
Bump golang.org/x/net from 0.1.0 to 0.2.0
2 years ago
dependabot[bot] f63a01a4de
Bump golang.org/x/net from 0.1.0 to 0.2.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.1.0 to 0.2.0.
- [Release notes](https://github.com/golang/net/releases)
- [Commits](https://github.com/golang/net/compare/v0.1.0...v0.2.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 years ago
Mariano Cano 7a8c6c0abe
Merge pull request #1179 from smallstep/changelog
Prepare changelog for v0.23.0 release
2 years ago
Mariano Cano 6d9c184e5a
Prepare changelog for v0.23.0 release 2 years ago
foleyjohnm d6f9b3336d
Update config.go 2 years ago
foleyjohnm c79d4e9316 adding CRLIDP config 2 years ago
Mariano Cano adad7ef970
Merge pull request #1177 from smallstep/fix-cli-738
Return an appropriate error when requests fail
2 years ago
Mariano Cano fcfd2b9bdc
Return an appropriate error when requests fail
If an http client Do method fails, it always returns an *url.URL error,
this change generalizes all those errors in one common method instead of
returning an fake HTTP error.

Fixes smallstep/cli#738
2 years ago
Herman Slatman 1f19b8ec5e
Merge pull request #1172 from smallstep/herman/remove-acme-cert-charset
Remove `charset=utf-8` from ACME certificate requests
2 years ago
Mariano Cano ffc30f49b1
Merge pull request #1174 from smallstep/fix-cli-730
Set dialer local address with STEP_CLIENT_ADDR
2 years ago
Mariano Cano a800ffe447
Merge pull request #1173 from smallstep/fix-1047
Create context for automatic RAs
2 years ago
Mariano Cano 47bd5a80d9
Set dialer local address with STEP_CLIENT_ADDR
The environment variable STEP_CLIENT_ADDR can be used to set the local
address to use when dialing an address. This can be useful when step
is behind an CIDR-based ACL.

Fixes smallstep/cli#730
2 years ago
Mariano Cano fa8d0a68c4
Merge pull request #1169 from smallstep/root-bundle
Allow root and federated root bundles
2 years ago
Mariano Cano 893147d23a
Create context for automatic RAs
It creates a new context with the given name if the flags --token
and --context are passed, and the context does not exist.

Fixes #1047
2 years ago
Herman Slatman 817edcbba5
Remove `charset=utf-8` from ACME certificate requests 2 years ago
Mariano Cano ddd5057f63
Allow root and federated root bundles
This commit changes the parsing of root and federated roots to support
a bundle of certificates, this makes easier to configure a root rotation
when using helm charts, just appending the old root.
2 years ago
Mariano Cano e0215e7243
Merge pull request #1167 from smallstep/linked-ra-renewal
Add support for linked RA renewals
2 years ago
Max ca6f4514fd
Merge pull request #1166 from smallstep/max/remove-docs
Remove deprecated docs directory
2 years ago
Mariano Cano 07c56f577a
Add support for linked RA renewals 2 years ago
Mariano Cano 3a89428b0f
Merge pull request #1165 from smallstep/upgrade-crypto
Upgrade go.step.sm/crypto
2 years ago
Mariano Cano b31cf1fc18
Fix merge and use last version of linkedca 2 years ago
Mariano Cano 2b928b1afd
Merge branch 'master' into upgrade-crypto 2 years ago
Herman Slatman 85cd9a1277
Fix some ACME DA doc strings (slightly) 2 years ago
Herman Slatman 4cf25ede24
Merge branch 'master' into herman/acme-da-tpm 2 years ago
Herman Slatman c169defc73
Merge pull request #1136 from smallstep/herman/ignore-empty-acme-meta 2 years ago
max furman dde9330244
Remove deprecated docs directory 2 years ago
Mariano Cano 75ac5d3889
Add ra renewal to the changelog 2 years ago
Mariano Cano 3ef73fa66b
Upgrade go.step.sm/crypto 2 years ago
Max 80cbcb652b
Merge pull request #1164 from smallstep/max/bad-comment
Correct bad comment on NotImplementedError.Error()
2 years ago
max furman 57c1c2071d
Correct bad comment on NotImplementedError.Error() 2 years ago
Mariano Cano e8726d24fa
Merge pull request #1156 from smallstep/ra-renew
Add support for renew when using stepcas
2 years ago
Max 202b17c3f2
Merge pull request #1159 from smallstep/dependabot/go_modules/cloud.google.com/go/security-1.10.0
Bump cloud.google.com/go/security from 1.9.0 to 1.10.0
2 years ago
dependabot[bot] ae684a557a
Bump cloud.google.com/go/security from 1.9.0 to 1.10.0
Bumps [cloud.google.com/go/security](https://github.com/googleapis/google-cloud-go) from 1.9.0 to 1.10.0.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/documentai/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/asset/v1.9.0...asset/v1.10.0)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/security
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 years ago
Max 7354e6e905
Merge pull request #1163 from smallstep/max/longrunning
Updates for deprecated google cloud security APIs
2 years ago
Herman Slatman 920c4f02c5
Add additional properties to provisioner converters 2 years ago
max furman e351bd90dc
Run make generate with mockgen@v1.6.0 2 years ago
Herman Slatman a7b2f5f27d
Upgrade `linkedca` to `v0.19.0-rc.4` 2 years ago
max furman 8f7fae585c
Add mockgen commands for cloudcas_test 2 years ago
Herman Slatman 1c4aa6ad79
Merge branch 'master' into herman/ignore-empty-acme-meta 2 years ago
max furman d4e81723ee
Updates for deprecated google cloud security APIs 2 years ago
Max 55a684fe5a
Merge pull request #1162 from smallstep/dependabot/go_modules/google.golang.org/api-0.102.0
Bump google.golang.org/api from 0.101.0 to 0.102.0
2 years ago
Max 4fcfc9481b
Merge pull request #1160 from smallstep/dependabot/go_modules/github.com/newrelic/go-agent/v3-3.20.0
Bump github.com/newrelic/go-agent/v3 from 3.19.2 to 3.20.0
2 years ago
dependabot[bot] 656b9ab217
Bump google.golang.org/api from 0.101.0 to 0.102.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.101.0 to 0.102.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.101.0...v0.102.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 years ago
Herman Slatman 9cbee4da33
Merge pull request #1158 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.23.0
Bump go.step.sm/crypto from 0.22.0 to 0.23.0
2 years ago
dependabot[bot] 88febefbcf
Bump github.com/newrelic/go-agent/v3 from 3.19.2 to 3.20.0
Bumps [github.com/newrelic/go-agent/v3](https://github.com/newrelic/go-agent) from 3.19.2 to 3.20.0.
- [Release notes](https://github.com/newrelic/go-agent/releases)
- [Changelog](https://github.com/newrelic/go-agent/blob/master/CHANGELOG.md)
- [Commits](https://github.com/newrelic/go-agent/compare/v3.19.2...v3.20.0)

---
updated-dependencies:
- dependency-name: github.com/newrelic/go-agent/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 years ago
dependabot[bot] 2891f6b397
Bump go.step.sm/crypto from 0.22.0 to 0.23.0
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.22.0 to 0.23.0.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.22.0...v0.23.0)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 years ago
Herman Slatman 3eae04928f
Add tests for ACME Meta object 2 years ago
Herman Slatman 02d679e160
Merge branch 'master' into herman/ignore-empty-acme-meta 2 years ago
Mariano Cano c7f226bcec
Add support for renew when using stepcas
It supports renewing X.509 certificates when an RA is configured with stepcas.
This will only work when the renewal uses a token, and it won't work with mTLS.

The audience cannot be properly verified when an RA is used, to avoid this we
will get from the database if an RA was used to issue the initial certificate
and we will accept the renew token.

Fixes #1021 for stepcas
2 years ago
Mariano Cano 068a2dae8e
Merge pull request #1155 from smallstep/acme-port-flags
Use the same style of flags
2 years ago
Mariano Cano e00781873e
Update commands/app.go
Co-authored-by: Max <mx.furman@gmail.com>
2 years ago
Mariano Cano bae9a0c152
Use the same style of flags
It changes the new step-ca flags to use a standard style.
2 years ago
Mariano Cano 6c0cb23125
Merge pull request #1153 from smallstep/acme-port
Add support for custom acme ports
2 years ago
Mariano Cano e27c6c529b
Add support for custom acme ports
This change adds the flags --acme-http-port, --acme-tls-port, that
combined with --insecure can be used to set custom ports for ACME
http-01 and tls-alpn-01 challenges. These flags should only be used
for testing purposes.

Fixes #1015
2 years ago
Max 9d90d0cef3
Merge pull request #1152 from smallstep/max/cosign-experimental
[action] Add COSIGN_EXPERIMENTAL env var to cosign release docs
2 years ago
max furman 3728cee02a
[action] Add COSIGN_EXPERIMENTAL env var to cosign release docs 2 years ago
Max be8c0b4531
Merge pull request #1151 from smallstep/max/gomod
go.mod syntax
2 years ago
max furman 4ccc9a0c32
go.mod syntax 2 years ago
Max 6136dbb196
Merge pull request #1147 from smallstep/dependabot/go_modules/cloud.google.com/go-0.105.0
Bump cloud.google.com/go from 0.104.0 to 0.105.0
2 years ago
dependabot[bot] bd577e7531
Bump cloud.google.com/go from 0.104.0 to 0.105.0
Bumps [cloud.google.com/go](https://github.com/googleapis/google-cloud-go) from 0.104.0 to 0.105.0.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/v0.104.0...v0.105.0)

---
updated-dependencies:
- dependency-name: cloud.google.com/go
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 years ago
Max e53a4b2ed5
Merge pull request #1149 from smallstep/dependabot/go_modules/go.step.sm/crypto-0.22.0
Bump go.step.sm/crypto from 0.21.0 to 0.22.0
2 years ago
dependabot[bot] 917d8dc103
Bump go.step.sm/crypto from 0.21.0 to 0.22.0
Bumps [go.step.sm/crypto](https://github.com/smallstep/crypto) from 0.21.0 to 0.22.0.
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.21.0...v0.22.0)

---
updated-dependencies:
- dependency-name: go.step.sm/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 years ago
Max b85b52d7b5
Merge pull request #1148 from smallstep/dependabot/go_modules/google.golang.org/api-0.101.0
Bump google.golang.org/api from 0.100.0 to 0.101.0
2 years ago
Max ea3f2fee7b
Merge pull request #1150 from smallstep/dependabot/go_modules/github.com/hashicorp/vault/api-1.8.2
Bump github.com/hashicorp/vault/api from 1.8.1 to 1.8.2
2 years ago
Max 9d9236c985
Merge pull request #1146 from smallstep/dependabot/go_modules/cloud.google.com/go/security-1.9.0
Bump cloud.google.com/go/security from 1.8.0 to 1.9.0
2 years ago
dependabot[bot] d26414a864
Bump github.com/hashicorp/vault/api from 1.8.1 to 1.8.2
Bumps [github.com/hashicorp/vault/api](https://github.com/hashicorp/vault) from 1.8.1 to 1.8.2.
- [Release notes](https://github.com/hashicorp/vault/releases)
- [Changelog](https://github.com/hashicorp/vault/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/vault/compare/v1.8.1...v1.8.2)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/vault/api
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2 years ago
dependabot[bot] 22d2c1c31f
Bump google.golang.org/api from 0.100.0 to 0.101.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.100.0 to 0.101.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.100.0...v0.101.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 years ago
dependabot[bot] 4e077f997e
Bump cloud.google.com/go/security from 1.8.0 to 1.9.0
Bumps [cloud.google.com/go/security](https://github.com/googleapis/google-cloud-go) from 1.8.0 to 1.9.0.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/documentai/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/asset/v1.8.0...asset/v1.9.0)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/security
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 years ago
Max 995b6d1b6c
Merge pull request #1142 from smallstep/max/keyless-cosign
[action] keyless cosign for all release artifacts
2 years ago
max furman c36b36f070
[action] cosign over docker image digest 2 years ago
Mariano Cano 3e0b603eb4
Merge pull request #731 from unreality/crl-support
Support for CRL
2 years ago
Mariano Cano 2d582e5694
Remove use of time.Duration.Abs
time.Duration.Abs() was added in Go 1.19
2 years ago
Mariano Cano 89c8c6d0a0
Fix package name in tls test 2 years ago
Mariano Cano f066ac3d40
Remove buggy logic on GetRevokedCertificates() 2 years ago
Mariano Cano 51c7f56030
Truncate time to the second 2 years ago
Mariano Cano 6d4fd7d016
Update changelog with CRL support 2 years ago
Mariano Cano 812fee7630
Start crl generator before setting initOnce 2 years ago
Mariano Cano 59775fff0c
Merge branch 'master' into crl-support 2 years ago
Mariano Cano 8200d19894
Improve CRL implementation
This commit adds some changes to PR #731, some of them are:
- Add distribution point to the CRL
- Properly stop the goroutine that generates the CRLs
- CRL config validation
- Remove expired certificates from the CRL
- Require enable set to true to generate a CRL

This last point is the principal change in behaviour from the previous
implementation. The CRL will not be generated if it's not enabled, and
if it is enabled it will always be regenerated at some point, not only
if there is a revocation.
2 years ago
max furman c43d59a69a
[action] keyless cosign for all release artifacts 2 years ago
Herman Slatman b9f238ad4d
Add additional ACME `meta` properties to provisioner configuration 2 years ago
Herman Slatman c9793561ff
Make `meta` object optional in ACME directory response
Harware appliances from Kemp seem to validate the contents of the
`meta` object, even if none of the properties in the `meta` object
is set. According to the RFC, the `meta` object, as well as its
properties are optional, so technically this should be fixed by
the manufacturer.

This commit is to see if we validation of the `meta` object is
skipped if it's not available in the response.
2 years ago
Raal Goff f7df865687 refactor crl config, add some tests 2 years ago
Raal Goff d0e81af524 Merge branch 'master' into crl-support 2 years ago
Herman Slatman a8125846dd
Add TPM attestation 2 years ago
Raal Goff 40baf73dff remove incorrect check on revoked certificate dates, add mutex lock for generating CRLs, 2 years ago
Mariano Cano 4e19aa4c52 Add cache duration if crl is set 2 years ago
Mariano Cano 221e756f40 Use render.Error on crl endpoint 2 years ago
Mariano Cano 0829f37fe8 Define a default crl cache duration 2 years ago
Mariano Cano 4a4f7ca9ba Fix panic if cacheDuration is not set 2 years ago
Raal Goff 924082bb49 fix linter errors 2 years ago
Raal Goff d2483f3a70 Merge branch 'master' into crl-support
# Conflicts:
#	authority/config/config.go
2 years ago
Raal Goff 9fa5f46213 add minor doco, Test_CRLGeneration(), fix some issues from merge 2 years ago
Raal Goff 60671b07d7 Merge branch 'master' into crl-support
# Conflicts:
#	api/api.go
#	authority/config/config.go
#	cas/softcas/softcas.go
#	db/db.go
2 years ago
Raal Goff c8b38c0e13 implemented requested changes 2 years ago
Raal Goff 773741eda8 Merge remote-tracking branch 'origin/crl-support' into crl-support
# Conflicts:
#	api/api_test.go
#	authority/tls.go
2 years ago
Raal Goff 49c41636cc implemented some requested changes 2 years ago
Raal Goff 53dbe2309b implemented some requested changes 2 years ago
Raal Goff a607ab189a requested changes 2 years ago
Raal Goff d417ce3232 implement changes from review 2 years ago
Raal Goff 668cb6f39c missed some mentions of PEM when changing the returned format to DER regarding CRL generation 2 years ago
Raal Goff 7d024cc4cb change GenerateCertificateRevocationList to return DER, store DER in db instead of PEM, nicer PEM encoding of CRL, add Mock stubs 2 years ago
Raal Goff e8fdb703c9 initial support for CRL 2 years ago
Raal Goff 8520c861d5 implemented some requested changes 2 years ago
Raal Goff 45975b061c requested changes 2 years ago
Raal Goff 222b52db13 implement changes from review 3 years ago
Raal Goff 26cb52a573 missed some mentions of PEM when changing the returned format to DER regarding CRL generation 3 years ago
Raal Goff 8545adea92 change GenerateCertificateRevocationList to return DER, store DER in db instead of PEM, nicer PEM encoding of CRL, add Mock stubs 3 years ago
Raal Goff 56926b9012 initial support for CRL 3 years ago

@ -9,3 +9,7 @@ updates:
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"

@ -20,7 +20,8 @@ jobs:
ci:
uses: smallstep/workflows/.github/workflows/goCI.yml@main
with:
os-dependencies: "libpcsclite-dev"
run-gitleaks: true
only-latest-golang: false
os-dependencies: 'libpcsclite-dev'
run-codeql: true
test-command: 'V=1 make test'
secrets: inherit

@ -5,5 +5,3 @@ on:
jobs:
code-scan:
uses: smallstep/workflows/.github/workflows/code-scan.yml@main
secrets:
GITLEAKS_LICENSE_KEY: ${{ secrets.GITLEAKS_LICENSE_KEY }}

@ -0,0 +1,11 @@
name: Dependabot auto-merge
on: pull_request
permissions:
contents: write
pull-requests: write
jobs:
dependabot-auto-merge:
uses: smallstep/workflows/.github/workflows/dependabot-auto-merge.yml@main
secrets: inherit

@ -13,10 +13,15 @@ jobs:
create_release:
name: Create Release
#needs: ci
runs-on: ubuntu-20.04
needs: ci
runs-on: ubuntu-latest
env:
DOCKER_IMAGE: smallstep/step-ca
outputs:
version: ${{ steps.extract-tag.outputs.VERSION }}
is_prerelease: ${{ steps.is_prerelease.outputs.IS_PRERELEASE }}
docker_tags: ${{ env.DOCKER_TAGS }}
docker_tags_hsm: ${{ env.DOCKER_TAGS_HSM }}
steps:
- name: Is Pre-release
id: is_prerelease
@ -25,77 +30,62 @@ jobs:
echo ${{ github.ref }} | grep "\-rc.*"
OUT=$?
if [ $OUT -eq 0 ]; then IS_PRERELEASE=true; else IS_PRERELEASE=false; fi
echo "::set-output name=IS_PRERELEASE::${IS_PRERELEASE}"
echo "IS_PRERELEASE=${IS_PRERELEASE}" >> "${GITHUB_OUTPUT}"
- name: Extract Tag Names
id: extract-tag
run: |
VERSION=${GITHUB_REF#refs/tags/v}
echo "VERSION=${VERSION}" >> "${GITHUB_OUTPUT}"
echo "DOCKER_TAGS=${{ env.DOCKER_IMAGE }}:${VERSION}" >> "${GITHUB_ENV}"
echo "DOCKER_TAGS_HSM=${{ env.DOCKER_IMAGE }}:${VERSION}-hsm" >> "${GITHUB_ENV}"
- name: Add Latest Tag
if: steps.is_prerelease.outputs.IS_PRERELEASE == 'false'
run: |
echo "DOCKER_TAGS=${{ env.DOCKER_TAGS }},${{ env.DOCKER_IMAGE }}:latest" >> "${GITHUB_ENV}"
echo "DOCKER_TAGS_HSM=${{ env.DOCKER_TAGS_HSM }},${{ env.DOCKER_IMAGE }}:hsm" >> "${GITHUB_ENV}"
- name: Create Release
id: create_release
uses: actions/create-release@v1
uses: softprops/action-gh-release@a74c6b72af54cfa997e81df42d94703d6313a2d0 # v2.0.6
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
name: Release ${{ github.ref }}
draft: false
prerelease: ${{ steps.is_prerelease.outputs.IS_PRERELEASE }}
goreleaser:
name: Upload Assets To Github w/ goreleaser
runs-on: ubuntu-20.04
needs: create_release
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.19
check-latest: true
- name: Install cosign
uses: sigstore/cosign-installer@v2.7.0
with:
cosign-release: 'v1.12.1'
- name: Write cosign key to disk
id: write_key
run: echo "${{ secrets.COSIGN_KEY }}" > "/tmp/cosign.key"
- name: Get Release Date
id: release_date
run: |
RELEASE_DATE=$(date +"%y-%m-%d")
echo "::set-output name=RELEASE_DATE::${RELEASE_DATE}"
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v3
with:
version: 'latest'
args: release --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.GORELEASER_PAT }}
COSIGN_PWD: ${{ secrets.COSIGN_PWD }}
RELEASE_DATE: ${{ steps.release_date.outputs.RELEASE_DATE }}
permissions:
id-token: write
contents: write
uses: smallstep/workflows/.github/workflows/goreleaser.yml@main
secrets: inherit
build_upload_docker:
name: Build & Upload Docker Images
runs-on: ubuntu-20.04
needs: ci
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Go
uses: actions/setup-go@v3
with:
go-version: '1.19'
check-latest: true
- name: Install cosign
uses: sigstore/cosign-installer@v1.1.0
with:
cosign-release: 'v1.1.0'
- name: Write cosign key to disk
id: write_key
run: echo "${{ secrets.COSIGN_KEY }}" > "/tmp/cosign.key"
- name: Build
id: build
run: |
PATH=$PATH:/usr/local/go/bin:/home/admin/go/bin
make docker-artifacts
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
COSIGN_PWD: ${{ secrets.COSIGN_PWD }}
needs: create_release
permissions:
id-token: write
contents: write
uses: smallstep/workflows/.github/workflows/docker-buildx-push.yml@main
with:
platforms: linux/amd64,linux/386,linux/arm,linux/arm64
tags: ${{ needs.create_release.outputs.docker_tags }}
docker_image: smallstep/step-ca
docker_file: docker/Dockerfile
secrets: inherit
build_upload_docker_hsm:
name: Build & Upload HSM Enabled Docker Images
needs: create_release
permissions:
id-token: write
contents: write
uses: smallstep/workflows/.github/workflows/docker-buildx-push.yml@main
with:
platforms: linux/amd64,linux/386,linux/arm,linux/arm64
tags: ${{ needs.create_release.outputs.docker_tags_hsm }}
docker_image: smallstep/step-ca
docker_file: docker/Dockerfile.hsm
secrets: inherit

@ -1,18 +0,0 @@
deac15327f5605a1a963e50818760a95cee9d882:docs/kms.md:generic-api-key:85
deac15327f5605a1a963e50818760a95cee9d882:docs/kms.md:generic-api-key:107
deac15327f5605a1a963e50818760a95cee9d882:docs/kms.md:generic-api-key:108
deac15327f5605a1a963e50818760a95cee9d882:docs/kms.md:generic-api-key:129
deac15327f5605a1a963e50818760a95cee9d882:docs/kms.md:generic-api-key:131
deac15327f5605a1a963e50818760a95cee9d882:docs/kms.md:generic-api-key:136
deac15327f5605a1a963e50818760a95cee9d882:docs/kms.md:generic-api-key:138
7c9ab9814fb676cb3c125c3dac4893271f1b7ae5:README.md:generic-api-key:282
fb7140444ac8f1fa1245a80e49d17e206f7435f3:docs/provisioners.md:generic-api-key:110
e4de7f07e82118b3f926716666b620db058fa9f7:docs/revocation.md:generic-api-key:73
e4de7f07e82118b3f926716666b620db058fa9f7:docs/revocation.md:generic-api-key:113
e4de7f07e82118b3f926716666b620db058fa9f7:docs/revocation.md:generic-api-key:151
8b2de42e9cf6ce99f53a5049881e1d6077d5d66e:docs/docker.md:generic-api-key:152
3939e855264117e81531df777a642ea953d325a7:autocert/init/ca/intermediate_ca_key:private-key:1
e72f08703753facfa05f2d8c68f9f6a3745824b8:README.md:generic-api-key:244
e70a5dae7de0b6ca40a0393c09c28872d4cfa071:autocert/README.md:generic-api-key:365
e70a5dae7de0b6ca40a0393c09c28872d4cfa071:autocert/README.md:generic-api-key:366
c284a2c0ab1c571a46443104be38c873ef0c7c6d:config.json:generic-api-key:10

@ -1,6 +1,6 @@
# This is an example .goreleaser.yml file with some sane defaults.
# Make sure to check the documentation at http://goreleaser.com
# Documentation: https://goreleaser.com/customization/
project_name: step-ca
version: 2
before:
hooks:
@ -31,7 +31,7 @@ builds:
- -w -X main.Version={{.Version}} -X main.BuildTime={{.Date}}
archives:
-
- &ARCHIVE
# Can be used to change the archive formats for specific GOOSs.
# Most common use case is to archive as zip on Windows.
# Default is empty.
@ -39,11 +39,16 @@ archives:
format_overrides:
- goos: windows
format: zip
wrap_in_directory: "{{ .ProjectName }}_{{ .Version }}"
files:
- README.md
- LICENSE
allow_different_binary_count: true
-
<< : *ARCHIVE
id: unversioned
name_template: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}"
wrap_in_directory: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}"
nfpms:
# Configure nFPM for .deb and .rpm releases
@ -55,7 +60,7 @@ nfpms:
# List file contents: dpkg -c dist/step_...deb
# Package metadata: dpkg --info dist/step_....deb
#
-
- &NFPM
builds:
- step-ca
package_name: step-ca
@ -75,6 +80,10 @@ nfpms:
contents:
- src: debian/copyright
dst: /usr/share/doc/step-ca/copyright
-
<< : *NFPM
id: unversioned
file_name_template: "{{ .PackageName }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}"
source:
enabled: true
@ -87,8 +96,9 @@ checksum:
signs:
- cmd: cosign
stdin: '{{ .Env.COSIGN_PWD }}'
args: ["sign-blob", "-key=/tmp/cosign.key", "-output-signature=${signature}", "${artifact}"]
signature: "${artifact}.sig"
certificate: "${artifact}.pem"
args: ["sign-blob", "--oidc-issuer=https://token.actions.githubusercontent.com", "--output-certificate=${certificate}", "--output-signature=${signature}", "${artifact}", "--yes"]
artifacts: all
snapshot:
@ -129,17 +139,17 @@ release:
#### Linux
- 📦 [step-ca_linux_{{ .Version }}_amd64.tar.gz](https://dl.step.sm/gh-release/certificates/gh-release-header/{{ .Tag }}/step-ca_linux_{{ .Version }}_amd64.tar.gz)
- 📦 [step-ca_{{ .Version }}_amd64.deb](https://dl.step.sm/gh-release/certificates/gh-release-header/{{ .Tag }}/step-ca_{{ .Version }}_amd64.deb)
- 📦 [step-ca_linux_{{ .Version }}_amd64.tar.gz](https://dl.smallstep.com/gh-release/certificates/gh-release-header/{{ .Tag }}/step-ca_linux_{{ .Version }}_amd64.tar.gz)
- 📦 [step-ca_{{ .Version }}_amd64.deb](https://dl.smallstep.com/gh-release/certificates/gh-release-header/{{ .Tag }}/step-ca_{{ .Version }}_amd64.deb)
#### OSX Darwin
- 📦 [step-ca_darwin_{{ .Version }}_amd64.tar.gz](https://dl.step.sm/gh-release/certificates/gh-release-header/{{ .Tag }}/step-ca_darwin_{{ .Version }}_amd64.tar.gz)
- 📦 [step-ca_darwin_{{ .Version }}_arm64.tar.gz](https://dl.step.sm/gh-release/certificates/gh-release-header/{{ .Tag }}/step-ca_darwin_{{ .Version }}_arm64.tar.gz)
- 📦 [step-ca_darwin_{{ .Version }}_amd64.tar.gz](https://dl.smallstep.com/gh-release/certificates/gh-release-header/{{ .Tag }}/step-ca_darwin_{{ .Version }}_amd64.tar.gz)
- 📦 [step-ca_darwin_{{ .Version }}_arm64.tar.gz](https://dl.smallstep.com/gh-release/certificates/gh-release-header/{{ .Tag }}/step-ca_darwin_{{ .Version }}_arm64.tar.gz)
#### Windows
- 📦 [step-ca_windows_{{ .Version }}_arm64.zip](https://dl.step.sm/gh-release/certificates/gh-release-header/{{ .Tag }}/step-ca_windows_{{ .Version }}_amd64.zip)
- 📦 [step-ca_windows_{{ .Version }}_amd64.zip](https://dl.smallstep.com/gh-release/certificates/gh-release-header/{{ .Tag }}/step-ca_windows_{{ .Version }}_amd64.zip)
For more builds across platforms and architectures, see the `Assets` section below.
And for packaged versions (Docker, k8s, Homebrew), see our [installation docs](https://smallstep.com/docs/step-ca/installation).
@ -154,9 +164,11 @@ release:
```
cosign verify-blob \
-key https://raw.githubusercontent.com/smallstep/certificates/master/cosign.pub \
-signature ~/Downloads/step-ca_darwin_{{ .Version }}_amd64.tar.gz.sig
~/Downloads/step-ca_darwin_{{ .Version }}_amd64.tar.gz
--certificate step-ca_darwin_{{ .Version }}_amd64.tar.gz.sig.pem \
--signature step-ca_darwin_{{ .Version }}_amd64.tar.gz.sig \
--certificate-identity-regexp "https://github\.com/smallstep/workflows/.*" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
step-ca_darwin_{{ .Version }}_amd64.tar.gz
```
The `checksums.txt` file (in the `Assets` section below) contains a checksum for every artifact in the release.
@ -168,7 +180,7 @@ release:
Those were the changes on {{ .Tag }}!
Come join us on [Discord](https://discord.gg/X2RKGwEbV9) to ask questions, chat about PKI, or get a sneak peak at the freshest PKI memes.
Come join us on [Discord](https://discord.gg/X2RKGwEbV9) to ask questions, chat about PKI, or get a sneak peek at the freshest PKI memes.
# You can disable this pipe in order to not upload any artifacts.
# Defaults to false.
@ -184,3 +196,160 @@ release:
# - glob: ./path/to/file.txt
# - glob: ./glob/**/to/**/file/**/*
# - glob: ./glob/foo/to/bar/file/foobar/override_from_previous
winget:
-
# IDs of the archives to use.
# Empty means all IDs.
ids: [ default ]
#
# Default: ProjectName
# Templates: allowed
name: step-ca
# Publisher name.
#
# Templates: allowed
# Required.
publisher: Smallstep
# Your app's description.
#
# Templates: allowed
# Required.
short_description: "A private certificate authority (X.509 & SSH) & ACME server for secure automated certificate management."
# License name.
#
# Templates: allowed
# Required.
license: "Apache-2.0"
# Publisher URL.
#
# Templates: allowed
publisher_url: "https://smallstep.com"
# Publisher support URL.
#
# Templates: allowed
publisher_support_url: "https://github.com/smallstep/certificates/discussions"
# URL which is determined by the given Token (github, gitlab or gitea).
#
# Default depends on the client.
# Templates: allowed
url_template: "https://github.com/smallstep/certificates/releases/download/{{ .Tag }}/{{ .ArtifactName }}"
# Git author used to commit to the repository.
commit_author:
name: goreleaserbot
email: goreleaser@smallstep.com
# The project name and current git tag are used in the format string.
#
# Templates: allowed
commit_msg_template: "{{ .PackageIdentifier }}: {{ .Tag }}"
# Your app's homepage.
homepage: "https://github.com/smallstep/certificates"
# Your app's long description.
#
# Templates: allowed
description: ""
# License URL.
#
# Templates: allowed
license_url: "https://github.com/smallstep/certificates/blob/master/LICENSE"
# Release notes URL.
#
# Templates: allowed
release_notes_url: "https://github.com/smallstep/certificates/releases/tag/{{ .Tag }}"
# Create the PR - for testing
skip_upload: auto
# Tags.
tags:
- certificates
- smallstep
- tls
# Repository to push the generated files to.
repository:
owner: smallstep
name: winget-pkgs
branch: "step-ca-{{.Version}}"
# Optionally a token can be provided, if it differs from the token
# provided to GoReleaser
# Templates: allowed
#token: "{{ .Env.GITHUB_PERSONAL_AUTH_TOKEN }}"
# Sets up pull request creation instead of just pushing to the given branch.
# Make sure the 'branch' property is different from base before enabling
# it.
#
# Since: v1.17
pull_request:
# Whether to enable it or not.
enabled: true
check_boxes: true
# Whether to open the PR as a draft or not.
#
# Default: false
# Since: v1.19
# draft: true
# Base can also be another repository, in which case the owner and name
# above will be used as HEAD, allowing cross-repository pull requests.
#
# Since: v1.19
base:
owner: microsoft
name: winget-pkgs
branch: master
scoops:
-
ids: [ default ]
# Template for the url which is determined by the given Token (github or gitlab)
# Default for github is "https://github.com/<repo_owner>/<repo_name>/releases/download/{{ .Tag }}/{{ .ArtifactName }}"
# Default for gitlab is "https://gitlab.com/<repo_owner>/<repo_name>/uploads/{{ .ArtifactUploadHash }}/{{ .ArtifactName }}"
# Default for gitea is "https://gitea.com/<repo_owner>/<repo_name>/releases/download/{{ .Tag }}/{{ .ArtifactName }}"
url_template: "http://github.com/smallstep/certificates/releases/download/{{ .Tag }}/{{ .ArtifactName }}"
# Repository to push the app manifest to.
repository:
owner: smallstep
name: scoop-bucket
branch: main
# Git author used to commit to the repository.
# Defaults are shown.
commit_author:
name: goreleaserbot
email: goreleaser@smallstep.com
# The project name and current git tag are used in the format string.
commit_msg_template: "Scoop update for {{ .ProjectName }} version {{ .Tag }}"
# Your app's homepage.
# Default is empty.
homepage: "https://smallstep.com/docs/step-ca"
# Skip uploads for prerelease.
skip_upload: auto
# Your app's description.
# Default is empty.
description: "A private certificate authority (X.509 & SSH) & ACME server for secure automated certificate management, so you can use TLS everywhere & SSO for SSH."
# Your app's license
# Default is empty.
license: "Apache-2.0"

@ -1,40 +1,327 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
### TEMPLATE -- do not alter or remove
## TEMPLATE -- do not alter or remove
---
## [x.y.z] - aaaa-bb-cc
### Added
### Changed
### Deprecated
### Removed
### Fixed
### Security
---
## [Unreleased]
## [0.26.2] - 2024-06-13
### Added
- Add provisionerID to ACME accounts (smallstep/certificates#1830)
- Enable verifying ACME provisioner using provisionerID if available (smallstep/certificates#1844)
- Add methods to Authority to get intermediate certificates (smallstep/certificates#1848)
- Add GetX509Signer method (smallstep/certificates#1850)
### Changed
- Make ISErrNotFound more flexible (smallstep/certificates#1819)
- Log errors using slog.Logger (smallstep/certificates#1849)
- Update hardcoded AWS certificates (smallstep/certificates#1881)
## [0.26.1] - 2024-04-22
### Added
- Allow configuration of a custom SCEP key manager (smallstep/certificates#1797)
### Fixed
- id-scep-failInfoText OID (smallstep/certificates#1794)
- CA startup with Vault RA configuration (smallstep/certificates#1803)
## [0.26.0] - 2024-03-28
### Added
- [TPM KMS](https://github.com/smallstep/crypto/tree/master/kms/tpmkms) support for CA keys (smallstep/certificates#1772)
- Propagation of HTTP request identifier using X-Request-Id header (smallstep/certificates#1743, smallstep/certificates#1542)
- Expires header in CRL response (smallstep/certificates#1708)
- Support for providing TLS configuration programmatically (smallstep/certificates#1685)
- Support for providing external CAS implementation (smallstep/certificates#1684)
- AWS `ca-west-1` identity document root certificate (smallstep/certificates#1715)
- [COSE RS1](https://www.rfc-editor.org/rfc/rfc8812.html#section-2) as a supported algorithm with ACME `device-attest-01` challenge (smallstep/certificates#1663)
### Changed
- In an RA setup, let the CA decide the RA certificate lifetime (smallstep/certificates#1764)
- Use Debian Bookworm in Docker containers (smallstep/certificates#1615)
- Error message for CSR validation (smallstep/certificates#1665)
- Updated dependencies
### Fixed
- Stop CA when any of the required servers fails to start (smallstep/certificates#1751). Before the fix, the CA would continue running and only log the server failure when stopped.
- Configuration loading errors when not using context were not returned. Fixed in [cli-utils/109](https://github.com/smallstep/cli-utils/pull/109).
- HTTP_PROXY and HTTPS_PROXY support for ACME validation client (smallstep/certificates#1658).
### Security
- Upgrade to using cosign v2 for signing artifacts
## [0.25.1] - 2023-11-28
### Added
- Provisioner name in SCEP webhook request body in (smallstep/certificates#1617)
- Support for ASN1 boolean encoding in (smallstep/certificates#1590)
### Changed
- Generation of first provisioner name on `step ca init` in (smallstep/certificates#1566)
- Processing of SCEP Get PKIOperation requests in (smallstep/certificates#1570)
- Support for signing identity certificate during SSH sign by skipping URI validation in (smallstep/certificates#1572)
- Dependency on `micromdm/scep` and `go.mozilla.org/pkcs7` to use Smallstep forks in (smallstep/certificates#1600)
- Make the Common Name validator for JWK provisioners accept values from SANs too in (smallstep/certificates#1609)
### Fixed
- Registration Authority token creation relied on values from CSR. Fixed to rely on template in (smallstep/certificates#1608)
- Use same glibc version for running the CA when built using CGo in (smallstep/certificates#1616)
## [0.25.0] - 2023-09-26
### Added
- Added support for configuring SCEP decrypters in the provisioner (smallstep/certificates#1414)
- Added support for TPM KMS (smallstep/crypto#253)
- Added support for disableSmallstepExtensions provisioner claim
(smallstep/certificates#1484)
- Added script to migrate a badger DB to MySQL or PostgreSQL
(smallstep/certificates#1477)
- Added AWS public certificates for me-central-1 and ap-southeast-3
(smallstep/certificates#1404)
- Added namespace field to VaultCAS JSON config (smallstep/certificates#1424)
- Added AWS public certificates for me-central-1 and ap-southeast-3
(smallstep/certificates#1404)
- Added unversioned filenames to Github release assets
(smallstep/certificates#1435)
- Send X5C leaf certificate to webhooks (smallstep/certificates#1485)
- Added support for disableSmallstepExtensions claim (smallstep/certificates#1484)
- Added all AWS Identity Document Certificates (smallstep/certificates#1404, smallstep/certificates#1510)
- Added Winget release automation (smallstep/certificates#1519)
- Added CSR to SCEPCHALLENGE webhook request body (smallstep/certificates#1523)
- Added SCEP issuance notification webhook (smallstep/certificates#1544)
- Added ability to disable color in the log text formatter
(smallstep/certificates(#1559)
### Changed
- Changed the Makefile to produce cgo-enabled builds running
`make build GO_ENVS="CGO_ENABLED=1"` (smallstep/certificates#1446)
- Return more detailed errors to ACME clients using device-attest-01
(smallstep/certificates#1495)
- Change SCEP password type to string (smallstep/certificates#1555)
### Removed
- Removed OIDC user regexp check (smallstep/certificates#1481)
- Removed automatic initialization of $STEPPATH (smallstep/certificates#1493)
- Removed db datasource from error msg to prevent leaking of secrets to logs
(smallstep/certificates#1528)
### Fixed
- Improved authentication for ACME requests using kid and provisioner name
(smallstep/certificates#1386).
- Fixed indentation of KMS configuration in helm charts
(smallstep/certificates#1405)
- Fixed simultaneous sign or decrypt operation on a YubiKey
(smallstep/certificates#1476, smallstep/crypto#288)
- Fixed adding certificate templates with ASN.1 functions
(smallstep/certificates#1500, smallstep/crypto#302)
- Fixed a problem when the ca.json is truncated if the encoding of the
configuration fails (e.g., new provisioner with bad template data)
(smallstep/cli#994, smallstep/certificates#1501)
- Fixed provisionerOptionsToLinkedCA missing template and templateData
(smallstep/certificates#1520)
- Fix calculation of webhook signature (smallstep/certificates#1546)
## [v0.24.2] - 2023-05-11
### Added
- Log SSH certificates (smallstep/certificates#1374)
- CRL endpoints on the HTTP server (smallstep/certificates#1372)
- Dynamic SCEP challenge validation using webhooks (smallstep/certificates#1366)
- For Docker deployments, added DOCKER_STEPCA_INIT_PASSWORD_FILE. Useful for pointing to a Docker Secret in the container (smallstep/certificates#1384)
### Changed
- Depend on [smallstep/go-attestation](https://github.com/smallstep/go-attestation) instead of [google/go-attestation](https://github.com/google/go-attestation)
- Render CRLs into http.ResponseWriter instead of memory (smallstep/certificates#1373)
- Redaction of SCEP static challenge when listing provisioners (smallstep/certificates#1204)
### Fixed
- VaultCAS certificate lifetime (smallstep/certificates#1376)
## [v0.24.1] - 2023-04-14
### Fixed
- Docker image name for HSM support (smallstep/certificates#1348)
## [v0.24.0] - 2023-04-12
### Added
- Add ACME `device-attest-01` support with TPM 2.0
(smallstep/certificates#1063).
- Add support for new Azure SDK, sovereign clouds, and HSM keys on Azure KMS
(smallstep/crypto#192, smallstep/crypto#197, smallstep/crypto#198,
smallstep/certificates#1323, smallstep/certificates#1309).
- Add support for ASN.1 functions on certificate templates
(smallstep/crypto#208, smallstep/certificates#1345)
- Add `DOCKER_STEPCA_INIT_ADDRESS` to configure the address to use in a docker
container (smallstep/certificates#1262).
- Make sure that the CSR used matches the attested key when using AME
`device-attest-01` challenge (smallstep/certificates#1265).
- Add support for compacting the Badger DB (smallstep/certificates#1298).
- Build and release cleanups (smallstep/certificates#1322,
smallstep/certificates#1329, smallstep/certificates#1340).
### Fixed
- Fix support for PKCS #7 RSA-OAEP decryption through
[smallstep/pkcs7#4](https://github.com/smallstep/pkcs7/pull/4), as used in
SCEP.
- Fix RA installation using `scripts/install-step-ra.sh`
(smallstep/certificates#1255).
- Clarify error messages on policy errors (smallstep/certificates#1287,
smallstep/certificates#1278).
- Clarify error message on OIDC email validation (smallstep/certificates#1290).
- Mark the IDP critical in the generated CRL data (smallstep/certificates#1293).
- Disable database if CA is initialized with the `--no-db` flag
(smallstep/certificates#1294).
## [v0.23.2] - 2023-02-02
### Added
- Added support for ACME device-attest-01 challenge.
- Added [`step-kms-plugin`](https://github.com/smallstep/step-kms-plugin) to
docker images, and a new image, `smallstep/step-ca-hsm`, compiled with cgo
(smallstep/certificates#1243).
- Added [`scoop`](https://scoop.sh) packages back to the release
(smallstep/certificates#1250).
- Added optional flag `--pidfile` which allows passing a filename where step-ca
will write its process id (smallstep/certificates#1251).
- Added helpful message on CA startup when config can't be opened
(smallstep/certificates#1252).
- Improved validation and error messages on `device-attest-01` orders
(smallstep/certificates#1235).
### Removed
- The deprecated CLI utils `step-awskms-init`, `step-cloudkms-init`,
`step-pkcs11-init`, `step-yubikey-init` have been removed.
[`step`](https://github.com/smallstep/cli) and
[`step-kms-plugin`](https://github.com/smallstep/step-kms-plugin) should be
used instead (smallstep/certificates#1240).
### Fixed
- Fixed remote management flags in docker images (smallstep/certificates#1228).
## [v0.23.1] - 2023-01-10
### Added
- Added configuration property `.crl.idpURL` to be able to set a custom Issuing
Distribution Point in the CRL (smallstep/certificates#1178).
- Added WithContext methods to the CA client (smallstep/certificates#1211).
- Docker: Added environment variables for enabling Remote Management and ACME
provisioner (smallstep/certificates#1201).
- Docker: The entrypoint script now generates and displays an initial JWK
provisioner password by default when the CA is being initialized
(smallstep/certificates#1223).
### Changed
- Ignore SSH principals validation when using an OIDC provisioner. The
provisioner will ignore the principals passed and set the defaults or the ones
including using WebHooks or templates (smallstep/certificates#1206).
## [v0.23.0] - 2022-11-11
### Added
- Added support for ACME device-attest-01 challenge on iOS, iPadOS, tvOS and
YubiKey.
- Ability to disable ACME challenges and attestation formats.
- Added flags to change ACME challenge ports for testing purposes.
- Added name constraints evaluation and enforcement when issuing or renewing
X.509 certificates.
- Added provisioner webhooks for augmenting template data and authorizing certificate requests before signing.
- Added automatic migration of provisioners when enabling remote managment.
- Added provisioner webhooks for augmenting template data and authorizing
certificate requests before signing.
- Added automatic migration of provisioners when enabling remote management.
- Added experimental support for CRLs.
- Add certificate renewal support on RA mode. The `step ca renew` command must
use the flag `--mtls=false` to use the token renewal flow.
- Added support for initializing remote management using `step ca init`.
- Added support for renewing X.509 certificates on RAs.
- Added support for using SCEP with keys in a KMS.
- Added client support to set the dialer's local address with the environment variable
`STEP_CLIENT_ADDR`.
### Changed
- Remove the email requirement for issuing SSH certificates with an OIDC
provisioner.
- Root files can contain more than one certificate.
### Fixed
- MySQL DSN parsing issues fixed with upgrade to [smallstep/nosql@v0.5.0](https://github.com/smallstep/nosql/releases/tag/v0.5.0).
- Fixed MySQL DSN parsing issues with an upgrade to
[smallstep/nosql@v0.5.0](https://github.com/smallstep/nosql/releases/tag/v0.5.0).
- Fixed renewal of certificates with missing subject attributes.
- Fixed ACME support with [ejabberd](https://github.com/processone/ejabberd).
### Deprecated
- The CLIs `step-awskms-init`, `step-cloudkms-init`, `step-pkcs11-init`,
`step-yubikey-init` are deprecated. Now you can use
[`step-kms-plugin`](https://github.com/smallstep/step-kms-plugin) in
combination with `step certificates create` to initialize your PKI.
## [0.22.1] - 2022-08-31
### Fixed
- Fixed signature algorithm on EC (root) + RSA (intermediate) PKIs.
## [0.22.0] - 2022-08-26
### Added
- Added automatic configuration of Linked RAs.
- Send provisioner configuration on Linked RAs.
### Changed
- Certificates signed by an issuer using an RSA key will be signed using the
same algorithm used to sign the issuer certificate. The signature will no
longer default to PKCS #1. For example, if the issuer certificate was signed
@ -46,20 +333,28 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Sanitize TLS options.
## [0.20.0] - 2022-05-26
### Added
- Added Kubernetes auth method for Vault RAs.
- Added support for reporting provisioners to linkedca.
- Added support for certificate policies on authority level.
- Added a Dockerfile with a step-ca build with HSM support.
- A few new WithXX methods for instantiating authorities
### Changed
- Context usage in HTTP APIs.
- Changed authentication for Vault RAs.
- Error message returned to client when authenticating with expired certificate.
- Strip padding from ACME CSRs.
### Deprecated
- HTTP API handler types.
### Fixed
- Fixed SSH revocation.
- CA client dial context for js/wasm target.
- Incomplete `extraNames` support in templates.
@ -67,7 +362,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Large SCEP request handling.
## [0.19.0] - 2022-04-19
### Added
- Added support for certificate renewals after expiry using the claim `allowRenewalAfterExpiry`.
- Added support for `extraNames` in X.509 templates.
- Added `armv5` builds.
@ -76,110 +373,162 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Added a new `/roots.pem` endpoint to download the CA roots in PEM format.
- Added support for Azure `Managed Identity` tokens.
- Added support for automatic configuration of linked RAs.
- Added support for the `--context` flag. It's now possible to start the
- Added support for the `--context` flag. It's now possible to start the
CA with `step-ca --context=abc` to use the configuration from context `abc`.
When a context has been configured and no configuration file is provided
on startup, the configuration for the current context is used.
- Added startup info logging and option to skip it (`--quiet`).
- Added support for renaming the CA (Common Name).
### Changed
- Made SCEP CA URL paths dynamic.
- Support two latest versions of Go (1.17, 1.18).
- Upgrade go.step.sm/crypto to v0.16.1.
- Upgrade go.step.sm/linkedca to v0.15.0.
### Deprecated
- Go 1.16 support.
### Removed
### Fixed
- Fixed admin credentials on RAs.
- Fixed ACME HTTP-01 challenges for IPv6 identifiers.
- Various improvements under the hood.
### Security
## [0.18.2] - 2022-03-01
### Added
- Added `subscriptionIDs` and `objectIDs` filters to the Azure provisioner.
- [NoSQL](https://github.com/smallstep/nosql/pull/21) package allows filtering
out database drivers using Go tags. For example, using the Go flag
`--tags=nobadger,nobbolt,nomysql` will only compile `step-ca` with the pgx
driver for PostgreSQL.
### Changed
- IPv6 addresses are normalized as IP addresses instead of hostnames.
- More descriptive JWK decryption error message.
- Make the X5C leaf certificate available to the templates using `{{ .AuthorizationCrt }}`.
### Fixed
- During provisioner add - validate provisioner configuration before storing to DB.
## [0.18.1] - 2022-02-03
### Added
- Support for ACME revocation.
- Replace hash function with an RSA SSH CA to "rsa-sha2-256".
- Support Nebula provisioners.
- Example Ansible configurations.
- Support PKCS#11 as a decrypter, as used by SCEP.
### Changed
- Automatically create database directory on `step ca init`.
- Slightly improve errors reported when a template has invalid content.
- Error reporting in logs and to clients.
### Fixed
- SCEP renewal using HTTPS on macOS.
## [0.18.0] - 2021-11-17
### Added
- Support for multiple certificate authority contexts.
- Support for generating extractable keys and certificates on a pkcs#11 module.
### Changed
- Support two latest versions of Go (1.16, 1.17)
### Deprecated
- go 1.15 support
## [0.17.6] - 2021-10-20
### Notes
- 0.17.5 failed in CI/CD
## [0.17.5] - 2021-10-20
### Added
- Support for Azure Key Vault as a KMS.
- Adapt `pki` package to support key managers.
- gocritic linter
### Fixed
- gocritic warnings
## [0.17.4] - 2021-09-28
### Fixed
- Support host-only or user-only SSH CA.
## [0.17.3] - 2021-09-24
### Added
- go 1.17 to github action test matrix
- Support for CloudKMS RSA-PSS signers without using templates.
- Add flags to support individual passwords for the intermediate and SSH keys.
- Global support for group admins in the OIDC provisioner.
### Changed
- Using go 1.17 for binaries
### Fixed
- Upgrade go-jose.v2 to fix a bug in the JWK fingerprint of Ed25519 keys.
### Security
- Use cosign to sign and upload signatures for multi-arch Docker container.
- Add debian checksum
## [0.17.2] - 2021-08-30
### Added
- Additional way to distinguish Azure IID and Azure OIDC tokens.
### Security
- Sign over all goreleaser github artifacts using cosign
## [0.17.1] - 2021-08-26
## [0.17.0] - 2021-08-25
### Added
- Add support for Linked CAs using protocol buffers and gRPC
- `step-ca init` adds support for
- configuring a StepCAS RA
- configuring a Linked CA
- congifuring a `step-ca` using Helm
### Changed
- Update badger driver to use v2 by default
- Update TLS cipher suites to include 1.3
### Security
- Fix key version when SHA512WithRSA is used. There was a typo creating RSA keys with SHA256 digests instead of SHA512.

@ -74,7 +74,7 @@ sudo yum install pcsc-lite-devel
To build `step-ca`, clone this repository and run the following:
```shell
make bootstrap && make build GOFLAGS=""
make bootstrap && make build GO_ENVS="CGO_ENABLED=1"
```
When the build is complete, you will find binaries in `bin/`.

@ -1,21 +1,11 @@
PKG?=github.com/smallstep/certificates/cmd/step-ca
BINNAME?=step-ca
CLOUDKMS_BINNAME?=step-cloudkms-init
CLOUDKMS_PKG?=github.com/smallstep/certificates/cmd/step-cloudkms-init
AWSKMS_BINNAME?=step-awskms-init
AWSKMS_PKG?=github.com/smallstep/certificates/cmd/step-awskms-init
YUBIKEY_BINNAME?=step-yubikey-init
YUBIKEY_PKG?=github.com/smallstep/certificates/cmd/step-yubikey-init
PKCS11_BINNAME?=step-pkcs11-init
PKCS11_PKG?=github.com/smallstep/certificates/cmd/step-pkcs11-init
# Set V to 1 for verbose output from the Makefile
Q=$(if $V,,@)
PREFIX?=
SRC=$(shell find . -type f -name '*.go' -not -path "./vendor/*")
GOOS_OVERRIDE ?=
OUTPUT_ROOT=output/
RELEASE=./.releases
all: lint test build
@ -31,6 +21,8 @@ bootstra%:
$Q curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $$(go env GOPATH)/bin latest
$Q go install golang.org/x/vuln/cmd/govulncheck@latest
$Q go install gotest.tools/gotestsum@latest
$Q go install github.com/goreleaser/goreleaser@latest
$Q go install github.com/sigstore/cosign/v2/cmd/cosign@latest
.PHONY: bootstra%
@ -38,17 +30,8 @@ bootstra%:
# Determine the type of `push` and `version`
#################################################
# If TRAVIS_TAG is set then we know this ref has been tagged.
ifdef TRAVIS_TAG
VERSION ?= $(TRAVIS_TAG)
NOT_RC := $(shell echo $(VERSION) | grep -v -e -rc)
ifeq ($(NOT_RC),)
PUSHTYPE := release-candidate
else
PUSHTYPE := release
endif
# GITHUB Actions
else ifdef GITHUB_REF
ifdef GITHUB_REF
VERSION ?= $(shell echo $(GITHUB_REF) | sed 's/^refs\/tags\///')
NOT_RC := $(shell echo $(VERSION) | grep -v -e -rc)
ifeq ($(NOT_RC),)
@ -61,59 +44,50 @@ VERSION ?= $(shell [ -d .git ] && git describe --tags --always --dirty="-dev")
# If we are not in an active git dir then try reading the version from .VERSION.
# .VERSION contains a slug populated by `git archive`.
VERSION := $(or $(VERSION),$(shell ./.version.sh .VERSION))
ifeq ($(TRAVIS_BRANCH),master)
PUSHTYPE := master
else
PUSHTYPE := branch
endif
endif
VERSION := $(shell echo $(VERSION) | sed 's/^v//')
DEB_VERSION := $(shell echo $(VERSION) | sed 's/-/./g')
ifdef V
$(info TRAVIS_TAG is $(TRAVIS_TAG))
$(info GITHUB_REF is $(GITHUB_REF))
$(info VERSION is $(VERSION))
$(info DEB_VERSION is $(DEB_VERSION))
$(info PUSHTYPE is $(PUSHTYPE))
endif
include make/docker.mk
#########################################
# Build
#########################################
DATE := $(shell date -u '+%Y-%m-%d %H:%M UTC')
LDFLAGS := -ldflags='-w -X "main.Version=$(VERSION)" -X "main.BuildTime=$(DATE)"'
GOFLAGS := CGO_ENABLED=0
# Always explicitly enable or disable cgo,
# so that go doesn't silently fall back on
# non-cgo when gcc is not found.
ifeq (,$(findstring CGO_ENABLED,$(GO_ENVS)))
ifneq ($(origin GOFLAGS),undefined)
# This section is for backward compatibility with
#
# $ make build GOFLAGS=""
#
# which is how we recommended building step-ca with cgo support
# until June 2023.
GO_ENVS := $(GO_ENVS) CGO_ENABLED=1
else
GO_ENVS := $(GO_ENVS) CGO_ENABLED=0
endif
endif
download:
$Q go mod download
build: $(PREFIX)bin/$(BINNAME) $(PREFIX)bin/$(CLOUDKMS_BINNAME) $(PREFIX)bin/$(AWSKMS_BINNAME) $(PREFIX)bin/$(YUBIKEY_BINNAME) $(PREFIX)bin/$(PKCS11_BINNAME)
build: $(PREFIX)bin/$(BINNAME)
@echo "Build Complete!"
$(PREFIX)bin/$(BINNAME): download $(call rwildcard,*.go)
$Q mkdir -p $(@D)
$Q $(GOOS_OVERRIDE) $(GOFLAGS) go build -v -o $(PREFIX)bin/$(BINNAME) $(LDFLAGS) $(PKG)
$(PREFIX)bin/$(CLOUDKMS_BINNAME): download $(call rwildcard,*.go)
$Q mkdir -p $(@D)
$Q $(GOOS_OVERRIDE) $(GOFLAGS) go build -v -o $(PREFIX)bin/$(CLOUDKMS_BINNAME) $(LDFLAGS) $(CLOUDKMS_PKG)
$(PREFIX)bin/$(AWSKMS_BINNAME): download $(call rwildcard,*.go)
$Q mkdir -p $(@D)
$Q $(GOOS_OVERRIDE) $(GOFLAGS) go build -v -o $(PREFIX)bin/$(AWSKMS_BINNAME) $(LDFLAGS) $(AWSKMS_PKG)
$(PREFIX)bin/$(YUBIKEY_BINNAME): download $(call rwildcard,*.go)
$Q mkdir -p $(@D)
$Q $(GOOS_OVERRIDE) $(GOFLAGS) go build -v -o $(PREFIX)bin/$(YUBIKEY_BINNAME) $(LDFLAGS) $(YUBIKEY_PKG)
$(PREFIX)bin/$(PKCS11_BINNAME): download $(call rwildcard,*.go)
$Q mkdir -p $(@D)
$Q $(GOOS_OVERRIDE) $(GOFLAGS) go build -v -o $(PREFIX)bin/$(PKCS11_BINNAME) $(LDFLAGS) $(PKCS11_PKG)
$Q $(GOOS_OVERRIDE) GOFLAGS="$(GOFLAGS)" $(GO_ENVS) go build -v -o $(PREFIX)bin/$(BINNAME) $(LDFLAGS) $(PKG)
# Target to force a build of step-ca without running tests
simple: build
@ -132,19 +106,26 @@ generate:
#########################################
# Test
#########################################
test:
$Q $(GOFLAGS) gotestsum -- -coverprofile=coverage.out -short -covermode=atomic ./...
test: testdefault testtpmsimulator combinecoverage
testdefault:
$Q $(GO_ENVS) gotestsum -- -coverprofile=defaultcoverage.out -short -covermode=atomic ./...
testtpmsimulator:
$Q CGO_ENABLED=1 gotestsum -- -coverprofile=tpmsimulatorcoverage.out -short -covermode=atomic -tags tpmsimulator ./acme
testcgo:
$Q gotestsum -- -coverprofile=coverage.out -short -covermode=atomic ./...
.PHONY: test testcgo
combinecoverage:
cat defaultcoverage.out tpmsimulatorcoverage.out > coverage.out
.PHONY: test testdefault testtpmsimulator testcgo combinecoverage
integrate: integration
integration: bin/$(BINNAME)
$Q $(GOFLAGS) gotestsum -- -tags=integration ./integration/...
$Q $(GO_ENVS) gotestsum -- -tags=integration ./integration/...
.PHONY: integrate integration
@ -168,15 +149,11 @@ lint:
INSTALL_PREFIX?=/usr/
install: $(PREFIX)bin/$(BINNAME) $(PREFIX)bin/$(CLOUDKMS_BINNAME) $(PREFIX)bin/$(AWSKMS_BINNAME)
install: $(PREFIX)bin/$(BINNAME)
$Q install -D $(PREFIX)bin/$(BINNAME) $(DESTDIR)$(INSTALL_PREFIX)bin/$(BINNAME)
$Q install -D $(PREFIX)bin/$(CLOUDKMS_BINNAME) $(DESTDIR)$(INSTALL_PREFIX)bin/$(CLOUDKMS_BINNAME)
$Q install -D $(PREFIX)bin/$(AWSKMS_BINNAME) $(DESTDIR)$(INSTALL_PREFIX)bin/$(AWSKMS_BINNAME)
uninstall:
$Q rm -f $(DESTDIR)$(INSTALL_PREFIX)/bin/$(BINNAME)
$Q rm -f $(DESTDIR)$(INSTALL_PREFIX)/bin/$(CLOUDKMS_BINNAME)
$Q rm -f $(DESTDIR)$(INSTALL_PREFIX)/bin/$(AWSKMS_BINNAME)
.PHONY: install uninstall
@ -188,18 +165,6 @@ clean:
ifneq ($(BINNAME),"")
$Q rm -f bin/$(BINNAME)
endif
ifneq ($(CLOUDKMS_BINNAME),"")
$Q rm -f bin/$(CLOUDKMS_BINNAME)
endif
ifneq ($(AWSKMS_BINNAME),"")
$Q rm -f bin/$(AWSKMS_BINNAME)
endif
ifneq ($(YUBIKEY_BINNAME),"")
$Q rm -f bin/$(YUBIKEY_BINNAME)
endif
ifneq ($(PKCS11_BINNAME),"")
$Q rm -f bin/$(PKCS11_BINNAME)
endif
.PHONY: clean
@ -212,31 +177,3 @@ run:
.PHONY: run
#########################################
# Debian
#########################################
changelog:
$Q echo "step-ca ($(DEB_VERSION)) unstable; urgency=medium" > debian/changelog
$Q echo >> debian/changelog
$Q echo " * See https://github.com/smallstep/certificates/releases" >> debian/changelog
$Q echo >> debian/changelog
$Q echo " -- Smallstep Labs, Inc. <techadmin@smallstep.com> $(shell date -uR)" >> debian/changelog
debian: changelog
$Q mkdir -p $(RELEASE); \
OUTPUT=../step-ca*.deb; \
rm $$OUTPUT; \
dpkg-buildpackage -b -rfakeroot -us -uc && cp $$OUTPUT $(RELEASE)/
distclean: clean
.PHONY: changelog debian distclean
#################################################
# Targets for creating step artifacts
#################################################
docker-artifacts: docker-$(PUSHTYPE)
.PHONY: docker-artifacts

@ -1,48 +1,61 @@
# Step Certificates
# step-ca
`step-ca` is an online certificate authority for secure, automated certificate management. It's the server counterpart to the [`step` CLI tool](https://github.com/smallstep/cli).
[![GitHub release](https://img.shields.io/github/release/smallstep/certificates.svg)](https://github.com/smallstep/certificates/releases/latest)
[![Go Report Card](https://goreportcard.com/badge/github.com/smallstep/certificates)](https://goreportcard.com/report/github.com/smallstep/certificates)
[![Build Status](https://github.com/smallstep/certificates/actions/workflows/test.yml/badge.svg)](https://github.com/smallstep/certificates)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
[![CLA assistant](https://cla-assistant.io/readme/badge/smallstep/certificates)](https://cla-assistant.io/smallstep/certificates)
`step-ca` is an online certificate authority for secure, automated certificate management for DevOps.
It's the server counterpart to the [`step` CLI tool](https://github.com/smallstep/cli) for working with certificates and keys.
Both projects are maintained by [Smallstep Labs](https://smallstep.com).
You can use it to:
- Issue X.509 certificates for your internal infrastructure:
- HTTPS certificates that [work in browsers](https://smallstep.com/blog/step-v0-8-6-valid-HTTPS-certificates-for-dev-pre-prod.html) ([RFC5280](https://tools.ietf.org/html/rfc5280) and [CA/Browser Forum](https://cabforum.org/baseline-requirements-documents/) compliance)
- TLS certificates for VMs, containers, APIs, mobile clients, database connections, printers, wifi networks, toaster ovens...
- Client certificates to [enable mutual TLS (mTLS)](https://smallstep.com/hello-mtls) in your infra. mTLS is an optional feature in TLS where both client and server authenticate each other. Why add the complexity of a VPN when you can safely use mTLS over the public internet?
You can use `step-ca` to:
- Issue HTTPS server and client certificates that [work in browsers](https://smallstep.com/blog/step-v0-8-6-valid-HTTPS-certificates-for-dev-pre-prod.html) ([RFC5280](https://tools.ietf.org/html/rfc5280) and [CA/Browser Forum](https://cabforum.org/baseline-requirements-documents/) compliance)
- Issue TLS certificates for DevOps: VMs, containers, APIs, database connections, Kubernetes pods...
- Issue SSH certificates:
- For people, in exchange for single sign-on ID tokens
- For people, in exchange for single sign-on identity tokens
- For hosts, in exchange for cloud instance identity documents
- Easily automate certificate management:
- It's an ACME v2 server
- It has a JSON API
- It's an [ACME server](https://smallstep.com/docs/step-ca/acme-basics/) that supports all [popular ACME challenge types](https://smallstep.com/docs/step-ca/acme-basics/#acme-challenge-types)
- It comes with a [Go wrapper](./examples#user-content-basic-client-usage)
- ... and there's a [command-line client](https://github.com/smallstep/cli) you can use in scripts!
Whatever your use case, `step-ca` is easy to use and hard to misuse, thanks to [safe, sane defaults](https://smallstep.com/docs/step-ca/certificate-authority-server-production#sane-cryptographic-defaults).
---
**Don't want to run your own CA?**
To get up and running quickly, or as an alternative to running your own `step-ca` server, consider creating a [free hosted smallstep Certificate Manager authority](https://info.smallstep.com/certificate-manager-early-access-mvp/).
### Comparison with Smallstep's commercial product
`step-ca` is optimized for a two-tier PKI serving common DevOps use cases.
As you design your PKI, if you need any of the following, [consider our commerical CA](http://smallstep.com):
- Multiple certificate authorities
- Active revocation (CRL, OSCP)
- Turnkey high-volume, high availability CA
- An API for seamless IaC management of your PKI
- Integrated support for SCEP & NDES, for migrating from legacy Active Directory Certificate Services deployments
- Device identity — cross-platform device inventory and attestation using Secure Enclave & TPM 2.0
- Highly automated PKI — managed certificate renewal, monitoring, TPM-based attested enrollment
- Seamless client deployments of EAP-TLS Wi-Fi, VPN, SSH, and browser certificates
- Jamf, Intune, or other MDM for root distribution and client enrollment
- Web Admin UI — history, issuance, and metrics
- ACME External Account Binding (EAB)
- Deep integration with an identity provider
- Fine-grained, role-based access control
- FIPS-compliant software
- HSM-bound private keys
See our [full feature comparison](https://smallstep.com/step-ca-vs-smallstep-certificate-manager/) for more.
You can [start a free trial](https://smallstep.com/signup) or [set up a call with us](https://go.smallstep.com/request-demo) to learn more.
---
**Questions? Find us in [Discussions](https://github.com/smallstep/certificates/discussions) or [Join our Discord](https://u.step.sm/discord).**
[Website](https://smallstep.com/certificates) |
[Documentation](https://smallstep.com/docs) |
[Documentation](https://smallstep.com/docs/step-ca) |
[Installation](https://smallstep.com/docs/step-ca/installation) |
[Getting Started](https://smallstep.com/docs/step-ca/getting-started) |
[Contributor's Guide](./docs/CONTRIBUTING.md)
[![GitHub release](https://img.shields.io/github/release/smallstep/certificates.svg)](https://github.com/smallstep/certificates/releases/latest)
[![Go Report Card](https://goreportcard.com/badge/github.com/smallstep/certificates)](https://goreportcard.com/report/github.com/smallstep/certificates)
[![Build Status](https://github.com/smallstep/certificates/actions/workflows/test.yml/badge.svg)](https://github.com/smallstep/certificates)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
[![CLA assistant](https://cla-assistant.io/readme/badge/smallstep/certificates)](https://cla-assistant.io/smallstep/certificates)
[![GitHub stars](https://img.shields.io/github/stars/smallstep/certificates.svg?style=social)](https://github.com/smallstep/certificates/stargazers)
[![Twitter followers](https://img.shields.io/twitter/follow/smallsteplabs.svg?label=Follow&style=social)](https://twitter.com/intent/follow?screen_name=smallsteplabs)
![star us](https://github.com/smallstep/certificates/raw/master/docs/images/star.gif)
[Contributor's Guide](./CONTRIBUTING.md)
## Features
@ -52,7 +65,6 @@ Setting up a *public key infrastructure* (PKI) is out of reach for many small te
- Choose key types (RSA, ECDSA, EdDSA) and lifetimes to suit your needs
- [Short-lived certificates](https://smallstep.com/blog/passive-revocation.html) with automated enrollment, renewal, and passive revocation
- Capable of high availability (HA) deployment using [root federation](https://smallstep.com/blog/step-v0.8.3-federation-root-rotation.html) and/or multiple intermediaries
- Can operate as [an online intermediate CA for an existing root CA](https://smallstep.com/docs/tutorials/intermediate-ca-new-ca)
- [Badger, BoltDB, Postgres, and MySQL database backends](https://smallstep.com/docs/step-ca/configuration#databases)
@ -119,19 +131,13 @@ See our installation docs [here](https://smallstep.com/docs/step-ca/installation
## Documentation
Documentation can be found in a handful of different places:
1. On the web at https://smallstep.com/docs/step-ca.
2. On the command line with `step help ca xxx` where `xxx` is the subcommand
you are interested in. Ex: `step help ca provisioner list`.
3. In your browser, by running `step help --http=:8080 ca` from the command line
* [Official documentation](https://smallstep.com/docs/step-ca) is on smallstep.com
* The `step` command reference is available via `step help`,
[on smallstep.com](https://smallstep.com/docs/step-cli/reference/),
or by running `step help --http=:8080` from the command line
and visiting http://localhost:8080.
4. The [docs](./docs/README.md) folder is being deprecated, but it still has some documentation and tutorials.
## Feedback?
* Tell us what you like and don't like about managing your PKI - we're eager to help solve problems in this space.
* Tell us about a feature you'd like to see! [Add a feature request Issue](https://github.com/smallstep/certificates/issues/new?assignees=&labels=enhancement%2C+needs+triage&template=enhancement.md&title=), [ask on Discussions](https://github.com/smallstep/certificates/discussions), or hit us up on [Twitter](https://twitter.com/smallsteplabs).
* Tell us what you like and don't like about managing your PKI - we're eager to help solve problems in this space. [Join our Discord](https://u.step.sm/discord) or [GitHub Discussions](https://github.com/smallstep/certificates/discussions)
* Tell us about a feature you'd like to see! [Request a Feature](https://github.com/smallstep/certificates/issues/new?assignees=&labels=enhancement%2C+needs+triage&template=enhancement.md&title=)

@ -20,6 +20,17 @@ type Account struct {
Status Status `json:"status"`
OrdersURL string `json:"orders"`
ExternalAccountBinding interface{} `json:"externalAccountBinding,omitempty"`
LocationPrefix string `json:"-"`
ProvisionerID string `json:"-"`
ProvisionerName string `json:"-"`
}
// GetLocation returns the URL location of the given account.
func (a *Account) GetLocation() string {
if a.LocationPrefix == "" {
return ""
}
return a.LocationPrefix + a.ID
}
// ToLog enables response logging.
@ -72,6 +83,7 @@ func (p *Policy) GetAllowedNameOptions() *policy.X509NameOptions {
IPRanges: p.X509.Allowed.IPRanges,
}
}
func (p *Policy) GetDeniedNameOptions() *policy.X509NameOptions {
if p == nil {
return nil

@ -25,7 +25,7 @@ func TestKeyToID(t *testing.T) {
jwk.Key = "foo"
return test{
jwk: jwk,
err: NewErrorISE("error generating jwk thumbprint: square/go-jose: unknown key type 'string'"),
err: NewErrorISE("error generating jwk thumbprint: go-jose/go-jose: unknown key type 'string'"),
}
},
"ok": func(t *testing.T) test {
@ -66,6 +66,23 @@ func TestKeyToID(t *testing.T) {
}
}
func TestAccount_GetLocation(t *testing.T) {
locationPrefix := "https://test.ca.smallstep.com/acme/foo/account/"
type test struct {
acc *Account
exp string
}
tests := map[string]test{
"empty": {acc: &Account{LocationPrefix: ""}, exp: ""},
"not-empty": {acc: &Account{ID: "bar", LocationPrefix: locationPrefix}, exp: locationPrefix + "bar"},
}
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
assert.Equals(t, tc.acc.GetLocation(), tc.exp)
})
}
}
func TestAccount_IsValid(t *testing.T) {
type test struct {
acc *Account
@ -135,7 +152,6 @@ func TestExternalAccountKey_BindTo(t *testing.T) {
if assert.True(t, errors.As(err, &ae)) {
assert.Equals(t, ae.Type, tt.err.Type)
assert.Equals(t, ae.Detail, tt.err.Detail)
assert.Equals(t, ae.Identifier, tt.err.Identifier)
assert.Equals(t, ae.Subproblems, tt.err.Subproblems)
}
} else {

@ -1,11 +1,12 @@
package api
import (
"context"
"encoding/json"
"errors"
"net/http"
"github.com/go-chi/chi"
"github.com/go-chi/chi/v5"
"github.com/smallstep/certificates/acme"
"github.com/smallstep/certificates/api/render"
@ -67,6 +68,12 @@ func (u *UpdateAccountRequest) Validate() error {
}
}
// getAccountLocationPath returns the current account URL location.
// Returned location will be of the form: https://<ca-url>/acme/<provisioner>/account/<accID>
func getAccountLocationPath(ctx context.Context, linker acme.Linker, accID string) string {
return linker.GetLink(ctx, acme.AccountLinkType, accID)
}
// NewAccount is the handler resource for creating new ACME accounts.
func NewAccount(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
@ -75,23 +82,23 @@ func NewAccount(w http.ResponseWriter, r *http.Request) {
payload, err := payloadFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
var nar NewAccountRequest
if err := json.Unmarshal(payload.value, &nar); err != nil {
render.Error(w, acme.WrapError(acme.ErrorMalformedType, err,
render.Error(w, r, acme.WrapError(acme.ErrorMalformedType, err,
"failed to unmarshal new-account request payload"))
return
}
if err := nar.Validate(); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
prov, err := acmeProvisionerFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
@ -101,46 +108,49 @@ func NewAccount(w http.ResponseWriter, r *http.Request) {
var acmeErr *acme.Error
if !errors.As(err, &acmeErr) || acmeErr.Status != http.StatusBadRequest {
// Something went wrong ...
render.Error(w, err)
render.Error(w, r, err)
return
}
// Account does not exist //
if nar.OnlyReturnExisting {
render.Error(w, acme.NewError(acme.ErrorAccountDoesNotExistType,
render.Error(w, r, acme.NewError(acme.ErrorAccountDoesNotExistType,
"account does not exist"))
return
}
jwk, err := jwkFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
eak, err := validateExternalAccountBinding(ctx, &nar)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
acc = &acme.Account{
Key: jwk,
Contact: nar.Contact,
Status: acme.StatusValid,
Key: jwk,
Contact: nar.Contact,
Status: acme.StatusValid,
LocationPrefix: getAccountLocationPath(ctx, linker, ""),
ProvisionerID: prov.ID,
ProvisionerName: prov.Name,
}
if err := db.CreateAccount(ctx, acc); err != nil {
render.Error(w, acme.WrapErrorISE(err, "error creating account"))
render.Error(w, r, acme.WrapErrorISE(err, "error creating account"))
return
}
if eak != nil { // means that we have a (valid) External Account Binding key that should be bound, updated and sent in the response
if err := eak.BindTo(acc); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
if err := db.UpdateExternalAccountKey(ctx, prov.ID, eak); err != nil {
render.Error(w, acme.WrapErrorISE(err, "error updating external account binding key"))
render.Error(w, r, acme.WrapErrorISE(err, "error updating external account binding key"))
return
}
acc.ExternalAccountBinding = nar.ExternalAccountBinding
@ -152,8 +162,8 @@ func NewAccount(w http.ResponseWriter, r *http.Request) {
linker.LinkAccount(ctx, acc)
w.Header().Set("Location", linker.GetLink(r.Context(), acme.AccountLinkType, acc.ID))
render.JSONStatus(w, acc, httpStatus)
w.Header().Set("Location", getAccountLocationPath(ctx, linker, acc.ID))
render.JSONStatus(w, r, acc, httpStatus)
}
// GetOrUpdateAccount is the api for updating an ACME account.
@ -164,12 +174,12 @@ func GetOrUpdateAccount(w http.ResponseWriter, r *http.Request) {
acc, err := accountFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
payload, err := payloadFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
@ -178,12 +188,12 @@ func GetOrUpdateAccount(w http.ResponseWriter, r *http.Request) {
if !payload.isPostAsGet {
var uar UpdateAccountRequest
if err := json.Unmarshal(payload.value, &uar); err != nil {
render.Error(w, acme.WrapError(acme.ErrorMalformedType, err,
render.Error(w, r, acme.WrapError(acme.ErrorMalformedType, err,
"failed to unmarshal new-account request payload"))
return
}
if err := uar.Validate(); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
if len(uar.Status) > 0 || len(uar.Contact) > 0 {
@ -194,7 +204,7 @@ func GetOrUpdateAccount(w http.ResponseWriter, r *http.Request) {
}
if err := db.UpdateAccount(ctx, acc); err != nil {
render.Error(w, acme.WrapErrorISE(err, "error updating account"))
render.Error(w, r, acme.WrapErrorISE(err, "error updating account"))
return
}
}
@ -203,7 +213,7 @@ func GetOrUpdateAccount(w http.ResponseWriter, r *http.Request) {
linker.LinkAccount(ctx, acc)
w.Header().Set("Location", linker.GetLink(ctx, acme.AccountLinkType, acc.ID))
render.JSON(w, acc)
render.JSON(w, r, acc)
}
func logOrdersByAccount(w http.ResponseWriter, oids []string) {
@ -223,23 +233,23 @@ func GetOrdersByAccountID(w http.ResponseWriter, r *http.Request) {
acc, err := accountFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
accID := chi.URLParam(r, "accID")
if acc.ID != accID {
render.Error(w, acme.NewError(acme.ErrorUnauthorizedType, "account ID '%s' does not match url param '%s'", acc.ID, accID))
render.Error(w, r, acme.NewError(acme.ErrorUnauthorizedType, "account ID '%s' does not match url param '%s'", acc.ID, accID))
return
}
orders, err := db.GetOrdersByAccountID(ctx, acc.ID)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
linker.LinkOrdersByAccountID(ctx, orders)
render.JSON(w, orders)
render.JSON(w, r, orders)
logOrdersByAccount(w, orders)
}

@ -7,12 +7,14 @@ import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/http/httptest"
"net/url"
"testing"
"time"
"github.com/go-chi/chi"
"github.com/go-chi/chi/v5"
"github.com/google/uuid"
"github.com/pkg/errors"
"go.step.sm/crypto/jose"
@ -34,35 +36,41 @@ var (
type fakeProvisioner struct{}
func (*fakeProvisioner) AuthorizeOrderIdentifier(ctx context.Context, identifier provisioner.ACMEIdentifier) error {
func (*fakeProvisioner) AuthorizeOrderIdentifier(context.Context, provisioner.ACMEIdentifier) error {
return nil
}
func (*fakeProvisioner) AuthorizeSign(ctx context.Context, token string) ([]provisioner.SignOption, error) {
func (*fakeProvisioner) AuthorizeSign(context.Context, string) ([]provisioner.SignOption, error) {
return nil, nil
}
func (*fakeProvisioner) IsChallengeEnabled(ctx context.Context, challenge provisioner.ACMEChallenge) bool {
func (*fakeProvisioner) IsChallengeEnabled(context.Context, provisioner.ACMEChallenge) bool {
return true
}
func (*fakeProvisioner) IsAttestationFormatEnabled(ctx context.Context, format provisioner.ACMEAttestationFormat) bool {
func (*fakeProvisioner) IsAttestationFormatEnabled(context.Context, provisioner.ACMEAttestationFormat) bool {
return true
}
func (*fakeProvisioner) GetAttestationRoots() (*x509.CertPool, bool) { return nil, false }
func (*fakeProvisioner) AuthorizeRevoke(context.Context, string) error { return nil }
func (*fakeProvisioner) GetID() string { return "" }
func (*fakeProvisioner) GetName() string { return "" }
func (*fakeProvisioner) DefaultTLSCertDuration() time.Duration { return 0 }
func (*fakeProvisioner) GetOptions() *provisioner.Options { return nil }
func (*fakeProvisioner) GetAttestationRoots() (*x509.CertPool, bool) {
return nil, false
func newProv() acme.Provisioner {
// Initialize provisioners
p := &provisioner.ACME{
Type: "ACME",
Name: "test@acme-<test>provisioner.com",
}
if err := p.Init(provisioner.Config{Claims: globalProvisionerClaims}); err != nil {
fmt.Printf("%v", err)
}
return p
}
func (*fakeProvisioner) AuthorizeRevoke(ctx context.Context, token string) error { return nil }
func (*fakeProvisioner) GetID() string { return "" }
func (*fakeProvisioner) GetName() string { return "" }
func (*fakeProvisioner) DefaultTLSCertDuration() time.Duration { return 0 }
func (*fakeProvisioner) GetOptions() *provisioner.Options { return nil }
func newProv() acme.Provisioner {
func newProvWithID() acme.Provisioner {
// Initialize provisioners
p := &provisioner.ACME{
ID: uuid.NewString(),
Type: "ACME",
Name: "test@acme-<test>provisioner.com",
}
@ -320,7 +328,7 @@ func TestHandler_GetOrdersByAccountID(t *testing.T) {
"fail/nil-account": func(t *testing.T) test {
return test{
db: &acme.MockDB{},
ctx: context.WithValue(context.Background(), accContextKey, nil),
ctx: context.WithValue(context.Background(), accContextKey, http.NoBody),
statusCode: 400,
err: acme.NewError(acme.ErrorAccountDoesNotExistType, "account does not exist"),
}
@ -370,7 +378,7 @@ func TestHandler_GetOrdersByAccountID(t *testing.T) {
tc := run(t)
t.Run(name, func(t *testing.T) {
ctx := acme.NewContext(tc.ctx, tc.db, nil, acme.NewLinker("test.ca.smallstep.com", "acme"), nil)
req := httptest.NewRequest("GET", u, nil)
req := httptest.NewRequest("GET", u, http.NoBody)
req = req.WithContext(ctx)
w := httptest.NewRecorder()
GetOrdersByAccountID(w, req)
@ -388,7 +396,6 @@ func TestHandler_GetOrdersByAccountID(t *testing.T) {
assert.Equals(t, ae.Type, tc.err.Type)
assert.Equals(t, ae.Detail, tc.err.Detail)
assert.Equals(t, ae.Identifier, tc.err.Identifier)
assert.Equals(t, ae.Subproblems, tc.err.Subproblems)
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
} else {
@ -810,7 +817,7 @@ func TestHandler_NewAccount(t *testing.T) {
tc := run(t)
t.Run(name, func(t *testing.T) {
ctx := acme.NewContext(tc.ctx, tc.db, nil, acme.NewLinker("test.ca.smallstep.com", "acme"), nil)
req := httptest.NewRequest("GET", "/foo/bar", nil)
req := httptest.NewRequest("GET", "/foo/bar", http.NoBody)
req = req.WithContext(ctx)
w := httptest.NewRecorder()
NewAccount(w, req)
@ -828,7 +835,6 @@ func TestHandler_NewAccount(t *testing.T) {
assert.Equals(t, ae.Type, tc.err.Type)
assert.Equals(t, ae.Detail, tc.err.Detail)
assert.Equals(t, ae.Identifier, tc.err.Identifier)
assert.Equals(t, ae.Subproblems, tc.err.Subproblems)
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
} else {
@ -1014,7 +1020,7 @@ func TestHandler_GetOrUpdateAccount(t *testing.T) {
tc := run(t)
t.Run(name, func(t *testing.T) {
ctx := acme.NewContext(tc.ctx, tc.db, nil, acme.NewLinker("test.ca.smallstep.com", "acme"), nil)
req := httptest.NewRequest("GET", "/foo/bar", nil)
req := httptest.NewRequest("GET", "/foo/bar", http.NoBody)
req = req.WithContext(ctx)
w := httptest.NewRecorder()
GetOrUpdateAccount(w, req)
@ -1032,7 +1038,6 @@ func TestHandler_GetOrUpdateAccount(t *testing.T) {
assert.Equals(t, ae.Type, tc.err.Type)
assert.Equals(t, ae.Detail, tc.err.Detail)
assert.Equals(t, ae.Identifier, tc.err.Identifier)
assert.Equals(t, ae.Subproblems, tc.err.Subproblems)
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
} else {

@ -866,7 +866,6 @@ func TestHandler_validateExternalAccountBinding(t *testing.T) {
assert.Equals(t, ae.Status, tc.err.Status)
assert.HasPrefix(t, ae.Err.Error(), tc.err.Err.Error())
assert.Equals(t, ae.Detail, tc.err.Detail)
assert.Equals(t, ae.Identifier, tc.err.Identifier)
assert.Equals(t, ae.Subproblems, tc.err.Subproblems)
}
} else {
@ -1145,7 +1144,6 @@ func Test_validateEABJWS(t *testing.T) {
assert.Equals(t, tc.err.Status, err.Status)
assert.HasPrefix(t, err.Err.Error(), tc.err.Err.Error())
assert.Equals(t, tc.err.Detail, err.Detail)
assert.Equals(t, tc.err.Identifier, err.Identifier)
assert.Equals(t, tc.err.Subproblems, err.Subproblems)
} else {
assert.Nil(t, err)

@ -9,7 +9,7 @@ import (
"net/http"
"time"
"github.com/go-chi/chi"
"github.com/go-chi/chi/v5"
"github.com/smallstep/certificates/acme"
"github.com/smallstep/certificates/api"
@ -205,7 +205,7 @@ type Directory struct {
NewOrder string `json:"newOrder"`
RevokeCert string `json:"revokeCert"`
KeyChange string `json:"keyChange"`
Meta Meta `json:"meta"`
Meta *Meta `json:"meta,omitempty"`
}
// ToLog enables response logging for the Directory type.
@ -223,27 +223,58 @@ func GetDirectory(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
acmeProv, err := acmeProvisionerFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
linker := acme.MustLinkerFromContext(ctx)
render.JSON(w, &Directory{
render.JSON(w, r, &Directory{
NewNonce: linker.GetLink(ctx, acme.NewNonceLinkType),
NewAccount: linker.GetLink(ctx, acme.NewAccountLinkType),
NewOrder: linker.GetLink(ctx, acme.NewOrderLinkType),
RevokeCert: linker.GetLink(ctx, acme.RevokeCertLinkType),
KeyChange: linker.GetLink(ctx, acme.KeyChangeLinkType),
Meta: Meta{
ExternalAccountRequired: acmeProv.RequireEAB,
},
Meta: createMetaObject(acmeProv),
})
}
// createMetaObject creates a Meta object if the ACME provisioner
// has one or more properties that are written in the ACME directory output.
// It returns nil if none of the properties are set.
func createMetaObject(p *provisioner.ACME) *Meta {
if shouldAddMetaObject(p) {
return &Meta{
TermsOfService: p.TermsOfService,
Website: p.Website,
CaaIdentities: p.CaaIdentities,
ExternalAccountRequired: p.RequireEAB,
}
}
return nil
}
// shouldAddMetaObject returns whether or not the ACME provisioner
// has properties configured that must be added to the ACME directory object.
func shouldAddMetaObject(p *provisioner.ACME) bool {
switch {
case p.TermsOfService != "":
return true
case p.Website != "":
return true
case len(p.CaaIdentities) > 0:
return true
case p.RequireEAB:
return true
default:
return false
}
}
// NotImplemented returns a 501 and is generally a placeholder for functionality which
// MAY be added at some point in the future but is not in any way a guarantee of such.
func NotImplemented(w http.ResponseWriter, r *http.Request) {
render.Error(w, acme.NewError(acme.ErrorNotImplementedType, "this API is not implemented"))
render.Error(w, r, acme.NewError(acme.ErrorNotImplementedType, "this API is not implemented"))
}
// GetAuthorization ACME api for retrieving an Authz.
@ -254,28 +285,28 @@ func GetAuthorization(w http.ResponseWriter, r *http.Request) {
acc, err := accountFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
az, err := db.GetAuthorization(ctx, chi.URLParam(r, "authzID"))
if err != nil {
render.Error(w, acme.WrapErrorISE(err, "error retrieving authorization"))
render.Error(w, r, acme.WrapErrorISE(err, "error retrieving authorization"))
return
}
if acc.ID != az.AccountID {
render.Error(w, acme.NewError(acme.ErrorUnauthorizedType,
render.Error(w, r, acme.NewError(acme.ErrorUnauthorizedType,
"account '%s' does not own authorization '%s'", acc.ID, az.ID))
return
}
if err = az.UpdateStatus(ctx, db); err != nil {
render.Error(w, acme.WrapErrorISE(err, "error updating authorization status"))
render.Error(w, r, acme.WrapErrorISE(err, "error updating authorization status"))
return
}
linker.LinkAuthorization(ctx, az)
w.Header().Set("Location", linker.GetLink(ctx, acme.AuthzLinkType, az.ID))
render.JSON(w, az)
render.JSON(w, r, az)
}
// GetChallenge ACME api for retrieving a Challenge.
@ -286,13 +317,13 @@ func GetChallenge(w http.ResponseWriter, r *http.Request) {
acc, err := accountFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
payload, err := payloadFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
@ -305,22 +336,22 @@ func GetChallenge(w http.ResponseWriter, r *http.Request) {
azID := chi.URLParam(r, "authzID")
ch, err := db.GetChallenge(ctx, chi.URLParam(r, "chID"), azID)
if err != nil {
render.Error(w, acme.WrapErrorISE(err, "error retrieving challenge"))
render.Error(w, r, acme.WrapErrorISE(err, "error retrieving challenge"))
return
}
ch.AuthorizationID = azID
if acc.ID != ch.AccountID {
render.Error(w, acme.NewError(acme.ErrorUnauthorizedType,
render.Error(w, r, acme.NewError(acme.ErrorUnauthorizedType,
"account '%s' does not own challenge '%s'", acc.ID, ch.ID))
return
}
jwk, err := jwkFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
if err = ch.Validate(ctx, db, jwk, payload.value); err != nil {
render.Error(w, acme.WrapErrorISE(err, "error validating challenge"))
render.Error(w, r, acme.WrapErrorISE(err, "error validating challenge"))
return
}
@ -328,7 +359,7 @@ func GetChallenge(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Link", link(linker.GetLink(ctx, acme.AuthzLinkType, azID), "up"))
w.Header().Set("Location", linker.GetLink(ctx, acme.ChallengeLinkType, azID, ch.ID))
render.JSON(w, ch)
render.JSON(w, r, ch)
}
// GetCertificate ACME api for retrieving a Certificate.
@ -338,18 +369,18 @@ func GetCertificate(w http.ResponseWriter, r *http.Request) {
acc, err := accountFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
certID := chi.URLParam(r, "certID")
cert, err := db.GetCertificate(ctx, certID)
if err != nil {
render.Error(w, acme.WrapErrorISE(err, "error retrieving certificate"))
render.Error(w, r, acme.WrapErrorISE(err, "error retrieving certificate"))
return
}
if cert.AccountID != acc.ID {
render.Error(w, acme.NewError(acme.ErrorUnauthorizedType,
render.Error(w, r, acme.NewError(acme.ErrorUnauthorizedType,
"account '%s' does not own certificate '%s'", acc.ID, certID))
return
}
@ -363,6 +394,6 @@ func GetCertificate(w http.ResponseWriter, r *http.Request) {
}
api.LogCertificate(w, cert.Leaf)
w.Header().Set("Content-Type", "application/pem-certificate-chain; charset=utf-8")
w.Header().Set("Content-Type", "application/pem-certificate-chain")
w.Write(certBytes)
}

@ -15,13 +15,16 @@ import (
"testing"
"time"
"github.com/go-chi/chi"
"github.com/go-chi/chi/v5"
"github.com/google/go-cmp/cmp"
"github.com/pkg/errors"
"github.com/smallstep/assert"
"github.com/smallstep/certificates/acme"
"go.step.sm/crypto/jose"
"go.step.sm/crypto/pemutil"
"github.com/smallstep/assert"
"github.com/smallstep/certificates/acme"
"github.com/smallstep/certificates/authority/provisioner"
)
type mockClient struct {
@ -57,7 +60,7 @@ func TestHandler_GetNonce(t *testing.T) {
}
// Request with chi context
req := httptest.NewRequest("GET", "http://ca.smallstep.com/nonce", nil)
req := httptest.NewRequest("GET", "http://ca.smallstep.com/nonce", http.NoBody)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@ -129,7 +132,35 @@ func TestHandler_GetDirectory(t *testing.T) {
NewOrder: fmt.Sprintf("%s/acme/%s/new-order", baseURL.String(), provName),
RevokeCert: fmt.Sprintf("%s/acme/%s/revoke-cert", baseURL.String(), provName),
KeyChange: fmt.Sprintf("%s/acme/%s/key-change", baseURL.String(), provName),
Meta: Meta{
Meta: &Meta{
ExternalAccountRequired: true,
},
}
return test{
ctx: ctx,
dir: expDir,
statusCode: 200,
}
},
"ok/full-meta": func(t *testing.T) test {
prov := newACMEProv(t)
prov.TermsOfService = "https://terms.ca.local/"
prov.Website = "https://ca.local/"
prov.CaaIdentities = []string{"ca.local"}
prov.RequireEAB = true
provName := url.PathEscape(prov.GetName())
baseURL := &url.URL{Scheme: "https", Host: "test.ca.smallstep.com"}
ctx := acme.NewProvisionerContext(context.Background(), prov)
expDir := Directory{
NewNonce: fmt.Sprintf("%s/acme/%s/new-nonce", baseURL.String(), provName),
NewAccount: fmt.Sprintf("%s/acme/%s/new-account", baseURL.String(), provName),
NewOrder: fmt.Sprintf("%s/acme/%s/new-order", baseURL.String(), provName),
RevokeCert: fmt.Sprintf("%s/acme/%s/revoke-cert", baseURL.String(), provName),
KeyChange: fmt.Sprintf("%s/acme/%s/key-change", baseURL.String(), provName),
Meta: &Meta{
TermsOfService: "https://terms.ca.local/",
Website: "https://ca.local/",
CaaIdentities: []string{"ca.local"},
ExternalAccountRequired: true,
},
}
@ -144,7 +175,7 @@ func TestHandler_GetDirectory(t *testing.T) {
tc := run(t)
t.Run(name, func(t *testing.T) {
ctx := acme.NewLinkerContext(tc.ctx, acme.NewLinker("test.ca.smallstep.com", "acme"))
req := httptest.NewRequest("GET", "/foo/bar", nil)
req := httptest.NewRequest("GET", "/foo/bar", http.NoBody)
req = req.WithContext(ctx)
w := httptest.NewRecorder()
GetDirectory(w, req)
@ -162,7 +193,6 @@ func TestHandler_GetDirectory(t *testing.T) {
assert.Equals(t, ae.Type, tc.err.Type)
assert.Equals(t, ae.Detail, tc.err.Detail)
assert.Equals(t, ae.Identifier, tc.err.Identifier)
assert.Equals(t, ae.Subproblems, tc.err.Subproblems)
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
} else {
@ -317,7 +347,7 @@ func TestHandler_GetAuthorization(t *testing.T) {
tc := run(t)
t.Run(name, func(t *testing.T) {
ctx := acme.NewContext(tc.ctx, tc.db, nil, acme.NewLinker("test.ca.smallstep.com", "acme"), nil)
req := httptest.NewRequest("GET", "/foo/bar", nil)
req := httptest.NewRequest("GET", "/foo/bar", http.NoBody)
req = req.WithContext(ctx)
w := httptest.NewRecorder()
GetAuthorization(w, req)
@ -335,7 +365,6 @@ func TestHandler_GetAuthorization(t *testing.T) {
assert.Equals(t, ae.Type, tc.err.Type)
assert.Equals(t, ae.Detail, tc.err.Detail)
assert.Equals(t, ae.Identifier, tc.err.Identifier)
assert.Equals(t, ae.Subproblems, tc.err.Subproblems)
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
} else {
@ -460,7 +489,7 @@ func TestHandler_GetCertificate(t *testing.T) {
tc := run(t)
t.Run(name, func(t *testing.T) {
ctx := acme.NewDatabaseContext(tc.ctx, tc.db)
req := httptest.NewRequest("GET", u, nil)
req := httptest.NewRequest("GET", u, http.NoBody)
req = req.WithContext(ctx)
w := httptest.NewRecorder()
GetCertificate(w, req)
@ -478,12 +507,11 @@ func TestHandler_GetCertificate(t *testing.T) {
assert.Equals(t, ae.Type, tc.err.Type)
assert.HasPrefix(t, ae.Detail, tc.err.Detail)
assert.Equals(t, ae.Identifier, tc.err.Identifier)
assert.Equals(t, ae.Subproblems, tc.err.Subproblems)
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
} else {
assert.Equals(t, bytes.TrimSpace(body), bytes.TrimSpace(certBytes))
assert.Equals(t, res.Header["Content-Type"], []string{"application/pem-certificate-chain; charset=utf-8"})
assert.Equals(t, res.Header["Content-Type"], []string{"application/pem-certificate-chain"})
}
})
}
@ -719,7 +747,7 @@ func TestHandler_GetChallenge(t *testing.T) {
tc := run(t)
t.Run(name, func(t *testing.T) {
ctx := acme.NewContext(tc.ctx, tc.db, nil, acme.NewLinker("test.ca.smallstep.com", "acme"), nil)
req := httptest.NewRequest("GET", u, nil)
req := httptest.NewRequest("GET", u, http.NoBody)
req = req.WithContext(ctx)
w := httptest.NewRecorder()
GetChallenge(w, req)
@ -737,7 +765,6 @@ func TestHandler_GetChallenge(t *testing.T) {
assert.Equals(t, ae.Type, tc.err.Type)
assert.Equals(t, ae.Detail, tc.err.Detail)
assert.Equals(t, ae.Identifier, tc.err.Identifier)
assert.Equals(t, ae.Subproblems, tc.err.Subproblems)
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
} else {
@ -751,3 +778,89 @@ func TestHandler_GetChallenge(t *testing.T) {
})
}
}
func Test_createMetaObject(t *testing.T) {
tests := []struct {
name string
p *provisioner.ACME
want *Meta
}{
{
name: "no-meta",
p: &provisioner.ACME{
Type: "ACME",
Name: "acme",
},
want: nil,
},
{
name: "terms-of-service",
p: &provisioner.ACME{
Type: "ACME",
Name: "acme",
TermsOfService: "https://terms.ca.local",
},
want: &Meta{
TermsOfService: "https://terms.ca.local",
},
},
{
name: "website",
p: &provisioner.ACME{
Type: "ACME",
Name: "acme",
Website: "https://ca.local",
},
want: &Meta{
Website: "https://ca.local",
},
},
{
name: "caa",
p: &provisioner.ACME{
Type: "ACME",
Name: "acme",
CaaIdentities: []string{"ca.local", "ca.remote"},
},
want: &Meta{
CaaIdentities: []string{"ca.local", "ca.remote"},
},
},
{
name: "require-eab",
p: &provisioner.ACME{
Type: "ACME",
Name: "acme",
RequireEAB: true,
},
want: &Meta{
ExternalAccountRequired: true,
},
},
{
name: "full-meta",
p: &provisioner.ACME{
Type: "ACME",
Name: "acme",
TermsOfService: "https://terms.ca.local",
Website: "https://ca.local",
CaaIdentities: []string{"ca.local", "ca.remote"},
RequireEAB: true,
},
want: &Meta{
TermsOfService: "https://terms.ca.local",
Website: "https://ca.local",
CaaIdentities: []string{"ca.local", "ca.remote"},
ExternalAccountRequired: true,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := createMetaObject(tt.p)
if !cmp.Equal(tt.want, got) {
t.Errorf("createMetaObject() diff =\n%s", cmp.Diff(tt.want, got))
}
})
}
}

@ -7,6 +7,7 @@ import (
"io"
"net/http"
"net/url"
"path"
"strings"
"go.step.sm/crypto/jose"
@ -16,7 +17,6 @@ import (
"github.com/smallstep/certificates/api/render"
"github.com/smallstep/certificates/authority/provisioner"
"github.com/smallstep/certificates/logging"
"github.com/smallstep/nosql"
)
type nextHTTP = func(http.ResponseWriter, *http.Request)
@ -36,7 +36,7 @@ func addNonce(next nextHTTP) nextHTTP {
db := acme.MustDatabaseFromContext(r.Context())
nonce, err := db.CreateNonce(r.Context())
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
w.Header().Set("Replay-Nonce", string(nonce))
@ -64,7 +64,7 @@ func verifyContentType(next nextHTTP) nextHTTP {
return func(w http.ResponseWriter, r *http.Request) {
p, err := provisionerFromContext(r.Context())
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
@ -88,7 +88,7 @@ func verifyContentType(next nextHTTP) nextHTTP {
return
}
}
render.Error(w, acme.NewError(acme.ErrorMalformedType,
render.Error(w, r, acme.NewError(acme.ErrorMalformedType,
"expected content-type to be in %s, but got %s", expected, ct))
}
}
@ -98,12 +98,12 @@ func parseJWS(next nextHTTP) nextHTTP {
return func(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
render.Error(w, acme.WrapErrorISE(err, "failed to read request body"))
render.Error(w, r, acme.WrapErrorISE(err, "failed to read request body"))
return
}
jws, err := jose.ParseJWS(string(body))
if err != nil {
render.Error(w, acme.WrapError(acme.ErrorMalformedType, err, "failed to parse JWS from request body"))
render.Error(w, r, acme.WrapError(acme.ErrorMalformedType, err, "failed to parse JWS from request body"))
return
}
ctx := context.WithValue(r.Context(), jwsContextKey, jws)
@ -133,26 +133,26 @@ func validateJWS(next nextHTTP) nextHTTP {
jws, err := jwsFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
if len(jws.Signatures) == 0 {
render.Error(w, acme.NewError(acme.ErrorMalformedType, "request body does not contain a signature"))
render.Error(w, r, acme.NewError(acme.ErrorMalformedType, "request body does not contain a signature"))
return
}
if len(jws.Signatures) > 1 {
render.Error(w, acme.NewError(acme.ErrorMalformedType, "request body contains more than one signature"))
render.Error(w, r, acme.NewError(acme.ErrorMalformedType, "request body contains more than one signature"))
return
}
sig := jws.Signatures[0]
uh := sig.Unprotected
if len(uh.KeyID) > 0 ||
if uh.KeyID != "" ||
uh.JSONWebKey != nil ||
len(uh.Algorithm) > 0 ||
len(uh.Nonce) > 0 ||
uh.Algorithm != "" ||
uh.Nonce != "" ||
len(uh.ExtraHeaders) > 0 {
render.Error(w, acme.NewError(acme.ErrorMalformedType, "unprotected header must not be used"))
render.Error(w, r, acme.NewError(acme.ErrorMalformedType, "unprotected header must not be used"))
return
}
hdr := sig.Protected
@ -162,13 +162,13 @@ func validateJWS(next nextHTTP) nextHTTP {
switch k := hdr.JSONWebKey.Key.(type) {
case *rsa.PublicKey:
if k.Size() < keyutil.MinRSAKeyBytes {
render.Error(w, acme.NewError(acme.ErrorMalformedType,
render.Error(w, r, acme.NewError(acme.ErrorMalformedType,
"rsa keys must be at least %d bits (%d bytes) in size",
8*keyutil.MinRSAKeyBytes, keyutil.MinRSAKeyBytes))
return
}
default:
render.Error(w, acme.NewError(acme.ErrorMalformedType,
render.Error(w, r, acme.NewError(acme.ErrorMalformedType,
"jws key type and algorithm do not match"))
return
}
@ -176,35 +176,35 @@ func validateJWS(next nextHTTP) nextHTTP {
case jose.ES256, jose.ES384, jose.ES512, jose.EdDSA:
// we good
default:
render.Error(w, acme.NewError(acme.ErrorBadSignatureAlgorithmType, "unsuitable algorithm: %s", hdr.Algorithm))
render.Error(w, r, acme.NewError(acme.ErrorBadSignatureAlgorithmType, "unsuitable algorithm: %s", hdr.Algorithm))
return
}
// Check the validity/freshness of the Nonce.
if err := db.DeleteNonce(ctx, acme.Nonce(hdr.Nonce)); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
// Check that the JWS url matches the requested url.
jwsURL, ok := hdr.ExtraHeaders["url"].(string)
if !ok {
render.Error(w, acme.NewError(acme.ErrorMalformedType, "jws missing url protected header"))
render.Error(w, r, acme.NewError(acme.ErrorMalformedType, "jws missing url protected header"))
return
}
reqURL := &url.URL{Scheme: "https", Host: r.Host, Path: r.URL.Path}
if jwsURL != reqURL.String() {
render.Error(w, acme.NewError(acme.ErrorMalformedType,
render.Error(w, r, acme.NewError(acme.ErrorMalformedType,
"url header in JWS (%s) does not match request url (%s)", jwsURL, reqURL))
return
}
if hdr.JSONWebKey != nil && len(hdr.KeyID) > 0 {
render.Error(w, acme.NewError(acme.ErrorMalformedType, "jwk and kid are mutually exclusive"))
if hdr.JSONWebKey != nil && hdr.KeyID != "" {
render.Error(w, r, acme.NewError(acme.ErrorMalformedType, "jwk and kid are mutually exclusive"))
return
}
if hdr.JSONWebKey == nil && hdr.KeyID == "" {
render.Error(w, acme.NewError(acme.ErrorMalformedType, "either jwk or kid must be defined in jws protected header"))
render.Error(w, r, acme.NewError(acme.ErrorMalformedType, "either jwk or kid must be defined in jws protected header"))
return
}
next(w, r)
@ -221,23 +221,23 @@ func extractJWK(next nextHTTP) nextHTTP {
jws, err := jwsFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
jwk := jws.Signatures[0].Protected.JSONWebKey
if jwk == nil {
render.Error(w, acme.NewError(acme.ErrorMalformedType, "jwk expected in protected header"))
render.Error(w, r, acme.NewError(acme.ErrorMalformedType, "jwk expected in protected header"))
return
}
if !jwk.Valid() {
render.Error(w, acme.NewError(acme.ErrorMalformedType, "invalid jwk in protected header"))
render.Error(w, r, acme.NewError(acme.ErrorMalformedType, "invalid jwk in protected header"))
return
}
// Overwrite KeyID with the JWK thumbprint.
jwk.KeyID, err = acme.KeyToID(jwk)
if err != nil {
render.Error(w, acme.WrapErrorISE(err, "error getting KeyID from JWK"))
render.Error(w, r, acme.WrapErrorISE(err, "error getting KeyID from JWK"))
return
}
@ -247,15 +247,15 @@ func extractJWK(next nextHTTP) nextHTTP {
// Get Account OR continue to generate a new one OR continue Revoke with certificate private key
acc, err := db.GetAccountByKeyID(ctx, jwk.KeyID)
switch {
case errors.Is(err, acme.ErrNotFound):
case acme.IsErrNotFound(err):
// For NewAccount and Revoke requests ...
break
case err != nil:
render.Error(w, err)
render.Error(w, r, err)
return
default:
if !acc.IsValid() {
render.Error(w, acme.NewError(acme.ErrorUnauthorizedType, "account is not active"))
render.Error(w, r, acme.NewError(acme.ErrorUnauthorizedType, "account is not active"))
return
}
ctx = context.WithValue(ctx, accContextKey, acc)
@ -274,11 +274,11 @@ func checkPrerequisites(next nextHTTP) nextHTTP {
if ok {
ok, err := checkFunc(ctx)
if err != nil {
render.Error(w, acme.WrapErrorISE(err, "error checking acme provisioner prerequisites"))
render.Error(w, r, acme.WrapErrorISE(err, "error checking acme provisioner prerequisites"))
return
}
if !ok {
render.Error(w, acme.NewError(acme.ErrorNotImplementedType, "acme provisioner configuration lacks prerequisites"))
render.Error(w, r, acme.NewError(acme.ErrorNotImplementedType, "acme provisioner configuration lacks prerequisites"))
return
}
}
@ -293,37 +293,74 @@ func lookupJWK(next nextHTTP) nextHTTP {
return func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
db := acme.MustDatabaseFromContext(ctx)
linker := acme.MustLinkerFromContext(ctx)
jws, err := jwsFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
kidPrefix := linker.GetLink(ctx, acme.AccountLinkType, "")
kid := jws.Signatures[0].Protected.KeyID
if !strings.HasPrefix(kid, kidPrefix) {
render.Error(w, acme.NewError(acme.ErrorMalformedType,
"kid does not have required prefix; expected %s, but got %s",
kidPrefix, kid))
if kid == "" {
render.Error(w, r, acme.NewError(acme.ErrorMalformedType, "signature missing 'kid'"))
return
}
accID := strings.TrimPrefix(kid, kidPrefix)
accID := path.Base(kid)
acc, err := db.GetAccount(ctx, accID)
switch {
case nosql.IsErrNotFound(err):
render.Error(w, acme.NewError(acme.ErrorAccountDoesNotExistType, "account with ID '%s' not found", accID))
case acme.IsErrNotFound(err):
render.Error(w, r, acme.NewError(acme.ErrorAccountDoesNotExistType, "account with ID '%s' not found", accID))
return
case err != nil:
render.Error(w, err)
render.Error(w, r, err)
return
default:
if !acc.IsValid() {
render.Error(w, acme.NewError(acme.ErrorUnauthorizedType, "account is not active"))
render.Error(w, r, acme.NewError(acme.ErrorUnauthorizedType, "account is not active"))
return
}
if storedLocation := acc.GetLocation(); storedLocation != "" {
if kid != storedLocation {
// ACME accounts should have a stored location equivalent to the
// kid in the ACME request.
render.Error(w, r, acme.NewError(acme.ErrorUnauthorizedType,
"kid does not match stored account location; expected %s, but got %s",
storedLocation, kid))
return
}
// Verify that the provisioner with which the account was created
// matches the provisioner in the request URL.
reqProv := acme.MustProvisionerFromContext(ctx)
switch {
case acc.ProvisionerID == "" && acc.ProvisionerName != reqProv.GetName():
render.Error(w, r, acme.NewError(acme.ErrorUnauthorizedType,
"account provisioner does not match requested provisioner; account provisioner = %s, requested provisioner = %s",
acc.ProvisionerName, reqProv.GetName()))
return
case acc.ProvisionerID != "" && acc.ProvisionerID != reqProv.GetID():
render.Error(w, r, acme.NewError(acme.ErrorUnauthorizedType,
"account provisioner does not match requested provisioner; account provisioner = %s, requested provisioner = %s",
acc.ProvisionerID, reqProv.GetID()))
return
}
} else {
// This code will only execute for old ACME accounts that do
// not have a cached location. The following validation was
// the original implementation of the `kid` check which has
// since been deprecated. However, the code will remain to
// ensure consistent behavior for old ACME accounts.
linker := acme.MustLinkerFromContext(ctx)
kidPrefix := linker.GetLink(ctx, acme.AccountLinkType, "")
if !strings.HasPrefix(kid, kidPrefix) {
render.Error(w, r, acme.NewError(acme.ErrorMalformedType,
"kid does not have required prefix; expected %s, but got %s",
kidPrefix, kid))
return
}
}
ctx = context.WithValue(ctx, accContextKey, acc)
ctx = context.WithValue(ctx, jwkContextKey, acc.Key)
next(w, r.WithContext(ctx))
@ -339,7 +376,7 @@ func extractOrLookupJWK(next nextHTTP) nextHTTP {
ctx := r.Context()
jws, err := jwsFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
@ -375,23 +412,32 @@ func verifyAndExtractJWSPayload(next nextHTTP) nextHTTP {
ctx := r.Context()
jws, err := jwsFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
jwk, err := jwkFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
if jwk.Algorithm != "" && jwk.Algorithm != jws.Signatures[0].Protected.Algorithm {
render.Error(w, acme.NewError(acme.ErrorMalformedType, "verifier and signature algorithm do not match"))
render.Error(w, r, acme.NewError(acme.ErrorMalformedType, "verifier and signature algorithm do not match"))
return
}
payload, err := jws.Verify(jwk)
if err != nil {
render.Error(w, acme.WrapError(acme.ErrorMalformedType, err, "error verifying jws"))
switch {
case errors.Is(err, jose.ErrCryptoFailure):
payload, err = retryVerificationWithPatchedSignatures(jws, jwk)
if err != nil {
render.Error(w, r, acme.WrapError(acme.ErrorMalformedType, err, "error verifying jws with patched signature(s)"))
return
}
case err != nil:
render.Error(w, r, acme.WrapError(acme.ErrorMalformedType, err, "error verifying jws"))
return
}
ctx = context.WithValue(ctx, payloadContextKey, &payloadInfo{
value: payload,
isPostAsGet: len(payload) == 0,
@ -401,16 +447,115 @@ func verifyAndExtractJWSPayload(next nextHTTP) nextHTTP {
}
}
// retryVerificationWithPatchedSignatures retries verification of the JWS using
// the JWK by patching the JWS signatures if they're determined to be too short.
//
// Generally this shouldn't happen, but we've observed this to be the case with
// the macOS ACME client, which seems to omit (at least one) leading null
// byte(s). The error returned is `go-jose/go-jose: error in cryptographic
// primitive`, which is a sentinel error that hides the details of the actual
// underlying error, which is as follows: `go-jose/go-jose: invalid signature
// size, have 63 bytes, wanted 64`, for ES256.
func retryVerificationWithPatchedSignatures(jws *jose.JSONWebSignature, jwk *jose.JSONWebKey) (data []byte, err error) {
originalSignatureValues := make([][]byte, len(jws.Signatures))
patched := false
defer func() {
if patched && err != nil {
for i, sig := range jws.Signatures {
sig.Signature = originalSignatureValues[i]
jws.Signatures[i] = sig
}
}
}()
for i, sig := range jws.Signatures {
var expectedSize int
alg := strings.ToUpper(sig.Header.Algorithm)
switch alg {
case jose.ES256:
expectedSize = 64
case jose.ES384:
expectedSize = 96
case jose.ES512:
expectedSize = 132
default:
// other cases are (currently) ignored
continue
}
switch diff := expectedSize - len(sig.Signature); diff {
case 0:
// expected length; nothing to do; will result in just doing the
// same verification (as done before calling this function) again,
// and thus an error will be returned.
continue
case 1:
patched = true
original := make([]byte, expectedSize-diff)
copy(original, sig.Signature)
originalSignatureValues[i] = original
patchedR := make([]byte, expectedSize)
copy(patchedR[1:], original) // [0x00, R.0:31, S.0:32], for expectedSize 64
sig.Signature = patchedR
jws.Signatures[i] = sig
// verify it with a patched R; return early if successful; continue
// with patching S if not.
data, err = jws.Verify(jwk)
if err == nil {
return
}
patchedS := make([]byte, expectedSize)
halfSize := expectedSize / 2
copy(patchedS, original[:halfSize]) // [R.0:32], for expectedSize 64
copy(patchedS[halfSize+1:], original[halfSize:]) // [R.0:32, 0x00, S.0:31]
sig.Signature = patchedS
jws.Signatures[i] = sig
case 2:
// assumption is currently the Apple case, in which only the
// first null byte of R and/or S are removed, and thus not a case in
// which two first bytes of either R or S are removed.
patched = true
original := make([]byte, expectedSize-diff)
copy(original, sig.Signature)
originalSignatureValues[i] = original
patchedRS := make([]byte, expectedSize)
halfSize := expectedSize / 2
copy(patchedRS[1:], original[:halfSize-1]) // [0x00, R.0:31], for expectedSize 64
copy(patchedRS[halfSize+1:], original[halfSize-1:]) // [0x00, R.0:31, 0x00, S.0:31]
sig.Signature = patchedRS
jws.Signatures[i] = sig
default:
// Technically, there can be multiple null bytes in either R or S,
// so when the difference is larger than 2, there is more than one
// option to pick. Apple's ACME client seems to only cut off the
// first null byte of either R or S, so we don't do anything in this
// case. Will result in just doing the same verification (as done
// before calling this function) again, and thus an error will be
// returned.
// TODO(hs): log this specific case? It might mean some other ACME
// client is doing weird things.
continue
}
}
data, err = jws.Verify(jwk)
return
}
// isPostAsGet asserts that the request is a PostAsGet (empty JWS payload).
func isPostAsGet(next nextHTTP) nextHTTP {
return func(w http.ResponseWriter, r *http.Request) {
payload, err := payloadFromContext(r.Context())
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
if !payload.isPostAsGet {
render.Error(w, acme.NewError(acme.ErrorMalformedType, "expected POST-as-GET"))
render.Error(w, r, acme.NewError(acme.ErrorMalformedType, "expected POST-as-GET"))
return
}
next(w, r)

@ -6,6 +6,7 @@ import (
"crypto"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
@ -14,17 +15,18 @@ import (
"strings"
"testing"
"github.com/pkg/errors"
"github.com/google/uuid"
"github.com/smallstep/assert"
"github.com/smallstep/certificates/acme"
"github.com/smallstep/nosql/database"
tassert "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.step.sm/crypto/jose"
"go.step.sm/crypto/keyutil"
)
var testBody = []byte("foo")
func testNext(w http.ResponseWriter, r *http.Request) {
func testNext(w http.ResponseWriter, _ *http.Request) {
w.Write(testBody)
}
@ -76,7 +78,7 @@ func TestHandler_addNonce(t *testing.T) {
tc := run(t)
t.Run(name, func(t *testing.T) {
ctx := newBaseContext(context.Background(), tc.db)
req := httptest.NewRequest("GET", u, nil).WithContext(ctx)
req := httptest.NewRequest("GET", u, http.NoBody).WithContext(ctx)
w := httptest.NewRecorder()
addNonce(testNext)(w, req)
res := w.Result()
@ -93,7 +95,6 @@ func TestHandler_addNonce(t *testing.T) {
assert.Equals(t, ae.Type, tc.err.Type)
assert.Equals(t, ae.Detail, tc.err.Detail)
assert.Equals(t, ae.Identifier, tc.err.Identifier)
assert.Equals(t, ae.Subproblems, tc.err.Subproblems)
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
} else {
@ -129,7 +130,7 @@ func TestHandler_addDirLink(t *testing.T) {
for name, run := range tests {
tc := run(t)
t.Run(name, func(t *testing.T) {
req := httptest.NewRequest("GET", "/foo", nil)
req := httptest.NewRequest("GET", "/foo", http.NoBody)
req = req.WithContext(tc.ctx)
w := httptest.NewRecorder()
addDirLink(testNext)(w, req)
@ -147,7 +148,6 @@ func TestHandler_addDirLink(t *testing.T) {
assert.Equals(t, ae.Type, tc.err.Type)
assert.Equals(t, ae.Detail, tc.err.Detail)
assert.Equals(t, ae.Identifier, tc.err.Identifier)
assert.Equals(t, ae.Subproblems, tc.err.Subproblems)
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
} else {
@ -233,7 +233,7 @@ func TestHandler_verifyContentType(t *testing.T) {
if tc.url != "" {
_u = tc.url
}
req := httptest.NewRequest("GET", _u, nil)
req := httptest.NewRequest("GET", _u, http.NoBody)
req = req.WithContext(tc.ctx)
req.Header.Add("Content-Type", tc.contentType)
w := httptest.NewRecorder()
@ -252,7 +252,6 @@ func TestHandler_verifyContentType(t *testing.T) {
assert.Equals(t, ae.Type, tc.err.Type)
assert.Equals(t, ae.Detail, tc.err.Detail)
assert.Equals(t, ae.Identifier, tc.err.Identifier)
assert.Equals(t, ae.Subproblems, tc.err.Subproblems)
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
} else {
@ -302,7 +301,7 @@ func TestHandler_isPostAsGet(t *testing.T) {
tc := run(t)
t.Run(name, func(t *testing.T) {
// h := &Handler{}
req := httptest.NewRequest("GET", u, nil)
req := httptest.NewRequest("GET", u, http.NoBody)
req = req.WithContext(tc.ctx)
w := httptest.NewRecorder()
isPostAsGet(testNext)(w, req)
@ -320,7 +319,6 @@ func TestHandler_isPostAsGet(t *testing.T) {
assert.Equals(t, ae.Type, tc.err.Type)
assert.Equals(t, ae.Detail, tc.err.Detail)
assert.Equals(t, ae.Identifier, tc.err.Identifier)
assert.Equals(t, ae.Subproblems, tc.err.Subproblems)
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
} else {
@ -332,7 +330,7 @@ func TestHandler_isPostAsGet(t *testing.T) {
type errReader int
func (errReader) Read(p []byte) (n int, err error) {
func (errReader) Read([]byte) (int, error) {
return 0, errors.New("force")
}
func (errReader) Close() error {
@ -359,7 +357,7 @@ func TestHandler_parseJWS(t *testing.T) {
return test{
body: strings.NewReader("foo"),
statusCode: 400,
err: acme.NewError(acme.ErrorMalformedType, "failed to parse JWS from request body: square/go-jose: compact JWS format must have three parts"),
err: acme.NewError(acme.ErrorMalformedType, "failed to parse JWS from request body: go-jose/go-jose: compact JWS format must have three parts"),
}
},
"ok": func(t *testing.T) test {
@ -410,7 +408,6 @@ func TestHandler_parseJWS(t *testing.T) {
assert.Equals(t, ae.Type, tc.err.Type)
assert.Equals(t, ae.Detail, tc.err.Detail)
assert.Equals(t, ae.Identifier, tc.err.Identifier)
assert.Equals(t, ae.Subproblems, tc.err.Subproblems)
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
} else {
@ -475,7 +472,7 @@ func TestHandler_verifyAndExtractJWSPayload(t *testing.T) {
err: acme.NewErrorISE("jwk expected in request context"),
}
},
"fail/verify-jws-failure": func(t *testing.T) test {
"fail/verify-jws-failure-wrong-jwk": func(t *testing.T) test {
_jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
assert.FatalError(t, err)
_pub := _jwk.Public()
@ -484,7 +481,34 @@ func TestHandler_verifyAndExtractJWSPayload(t *testing.T) {
return test{
ctx: ctx,
statusCode: 400,
err: acme.NewError(acme.ErrorMalformedType, "error verifying jws: square/go-jose: error in cryptographic primitive"),
err: acme.NewError(acme.ErrorMalformedType, "error verifying jws: go-jose/go-jose: error in cryptographic primitive"),
}
},
"fail/verify-jws-failure-too-many-signatures": func(t *testing.T) test {
newParsedJWS, err := jose.ParseJWS(raw)
assert.FatalError(t, err)
newParsedJWS.Signatures = append(newParsedJWS.Signatures, newParsedJWS.Signatures...)
ctx := context.WithValue(context.Background(), jwsContextKey, newParsedJWS)
ctx = context.WithValue(ctx, jwkContextKey, pub)
return test{
ctx: ctx,
statusCode: 400,
err: acme.NewError(acme.ErrorMalformedType, "error verifying jws: go-jose/go-jose: too many signatures in payload; expecting only one"),
}
},
"fail/apple-acmeclient-omitting-leading-null-byte-in-signature-with-wrong-jwk": func(t *testing.T) test {
_jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
assert.FatalError(t, err)
_pub := _jwk.Public()
appleNullByteCaseBody := `{"payload":"dGVzdC0xMTA1","protected":"eyJhbGciOiJFUzI1NiJ9","signature":"rQPYKYflfKnlgBKqDeWsJH2TJ6iHAnou7sFzXlmYD4ArXqLfYuqotWERKrna2wfzh0pu7USWO2gzlOqRK9qq"}`
appleNullByteCaseJWS, err := jose.ParseJWS(appleNullByteCaseBody)
require.NoError(t, err)
ctx := context.WithValue(context.Background(), jwsContextKey, appleNullByteCaseJWS)
ctx = context.WithValue(ctx, jwkContextKey, &_pub)
return test{
ctx: ctx,
statusCode: 400,
err: acme.NewError(acme.ErrorMalformedType, "error verifying jws: go-jose/go-jose: error in cryptographic primitive"),
}
},
"fail/algorithm-mismatch": func(t *testing.T) test {
@ -583,12 +607,44 @@ func TestHandler_verifyAndExtractJWSPayload(t *testing.T) {
},
}
},
"ok/apple-acmeclient-omitting-leading-null-byte-in-signature": func(t *testing.T) test {
appleNullByteCaseKey := []byte(`{
"kid": "uioinbiTlJICL0MYsb6ar1totfRA2tiPqWgntF8xUdo",
"crv": "P-256",
"alg": "ES256",
"kty": "EC",
"x": "wlz-Kv9X0h32fzLq-cogls9HxoZQqV-GuWxdb2MCeUY",
"y": "xzP6zRrg_jynYljZTxfJuql_QWtdQR6lpJ52q_6Vavg"
}`)
appleNullByteCaseJWK := &jose.JSONWebKey{}
err = json.Unmarshal(appleNullByteCaseKey, appleNullByteCaseJWK)
require.NoError(t, err)
appleNullByteCaseBody := `{"payload":"dGVzdC0xMTA1","protected":"eyJhbGciOiJFUzI1NiJ9","signature":"rQPYKYflfKnlgBKqDeWsJH2TJ6iHAnou7sFzXlmYD4ArXqLfYuqotWERKrna2wfzh0pu7USWO2gzlOqRK9qq"}`
appleNullByteCaseJWS, err := jose.ParseJWS(appleNullByteCaseBody)
require.NoError(t, err)
ctx := context.WithValue(context.Background(), jwsContextKey, appleNullByteCaseJWS)
ctx = context.WithValue(ctx, jwkContextKey, appleNullByteCaseJWK)
return test{
ctx: ctx,
statusCode: 200,
next: func(w http.ResponseWriter, r *http.Request) {
p, err := payloadFromContext(r.Context())
tassert.NoError(t, err)
if tassert.NotNil(t, p) {
tassert.Equal(t, []byte(`test-1105`), p.value)
tassert.False(t, p.isPostAsGet)
tassert.False(t, p.isEmptyJSON)
}
w.Write(testBody)
},
}
},
}
for name, run := range tests {
tc := run(t)
t.Run(name, func(t *testing.T) {
// h := &Handler{}
req := httptest.NewRequest("GET", u, nil)
req := httptest.NewRequest("GET", u, http.NoBody)
req = req.WithContext(tc.ctx)
w := httptest.NewRecorder()
verifyAndExtractJWSPayload(tc.next)(w, req)
@ -606,7 +662,6 @@ func TestHandler_verifyAndExtractJWSPayload(t *testing.T) {
assert.Equals(t, ae.Type, tc.err.Type)
assert.Equals(t, ae.Detail, tc.err.Detail)
assert.Equals(t, ae.Identifier, tc.err.Identifier)
assert.Equals(t, ae.Subproblems, tc.err.Subproblems)
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
} else {
@ -684,31 +739,7 @@ func TestHandler_lookupJWK(t *testing.T) {
linker: acme.NewLinker("test.ca.smallstep.com", "acme"),
ctx: ctx,
statusCode: 400,
err: acme.NewError(acme.ErrorMalformedType, "kid does not have required prefix; expected %s, but got ", prefix),
}
},
"fail/bad-kid-prefix": func(t *testing.T) test {
_so := new(jose.SignerOptions)
_so.WithHeader("kid", "foo")
_signer, err := jose.NewSigner(jose.SigningKey{
Algorithm: jose.SignatureAlgorithm(jwk.Algorithm),
Key: jwk.Key,
}, _so)
assert.FatalError(t, err)
_jws, err := _signer.Sign([]byte("baz"))
assert.FatalError(t, err)
_raw, err := _jws.CompactSerialize()
assert.FatalError(t, err)
_parsed, err := jose.ParseJWS(_raw)
assert.FatalError(t, err)
ctx := acme.NewProvisionerContext(context.Background(), prov)
ctx = context.WithValue(ctx, jwsContextKey, _parsed)
return test{
db: &acme.MockDB{},
linker: acme.NewLinker("test.ca.smallstep.com", "acme"),
ctx: ctx,
statusCode: 400,
err: acme.NewError(acme.ErrorMalformedType, "kid does not have required prefix; expected %s, but got foo", prefix),
err: acme.NewError(acme.ErrorMalformedType, "signature missing 'kid'"),
}
},
"fail/account-not-found": func(t *testing.T) test {
@ -719,7 +750,7 @@ func TestHandler_lookupJWK(t *testing.T) {
db: &acme.MockDB{
MockGetAccount: func(ctx context.Context, accID string) (*acme.Account, error) {
assert.Equals(t, accID, accID)
return nil, database.ErrNotFound
return nil, acme.ErrNotFound
},
},
ctx: ctx,
@ -760,7 +791,106 @@ func TestHandler_lookupJWK(t *testing.T) {
err: acme.NewError(acme.ErrorUnauthorizedType, "account is not active"),
}
},
"ok": func(t *testing.T) test {
"fail/account-with-location-prefix/bad-kid": func(t *testing.T) test {
acc := &acme.Account{LocationPrefix: "foobar", Status: "valid"}
ctx := acme.NewProvisionerContext(context.Background(), prov)
ctx = context.WithValue(ctx, jwsContextKey, parsedJWS)
return test{
linker: acme.NewLinker("test.ca.smallstep.com", "acme"),
db: &acme.MockDB{
MockGetAccount: func(ctx context.Context, id string) (*acme.Account, error) {
assert.Equals(t, id, accID)
return acc, nil
},
},
ctx: ctx,
statusCode: http.StatusUnauthorized,
err: acme.NewError(acme.ErrorUnauthorizedType, "kid does not match stored account location; expected foobar, but %q", prefix+accID),
}
},
"fail/account-with-location-prefix/bad-provisioner": func(t *testing.T) test {
acc := &acme.Account{LocationPrefix: prefix + accID, Status: "valid", Key: jwk, ProvisionerName: "other"}
ctx := acme.NewProvisionerContext(context.Background(), prov)
ctx = context.WithValue(ctx, jwsContextKey, parsedJWS)
return test{
linker: acme.NewLinker("test.ca.smallstep.com", "acme"),
db: &acme.MockDB{
MockGetAccount: func(ctx context.Context, id string) (*acme.Account, error) {
assert.Equals(t, id, accID)
return acc, nil
},
},
ctx: ctx,
next: func(w http.ResponseWriter, r *http.Request) {
_acc, err := accountFromContext(r.Context())
assert.FatalError(t, err)
assert.Equals(t, _acc, acc)
_jwk, err := jwkFromContext(r.Context())
assert.FatalError(t, err)
assert.Equals(t, _jwk, jwk)
w.Write(testBody)
},
statusCode: http.StatusUnauthorized,
err: acme.NewError(acme.ErrorUnauthorizedType,
"account provisioner does not match requested provisioner; account provisioner = %s, requested provisioner = %s",
"other", prov.GetName()),
}
},
"fail/account-with-location-prefix/bad-provisioner-id": func(t *testing.T) test {
p := newProvWithID()
acc := &acme.Account{LocationPrefix: prefix + accID, Status: "valid", Key: jwk, ProvisionerID: uuid.NewString()}
ctx := acme.NewProvisionerContext(context.Background(), p)
ctx = context.WithValue(ctx, jwsContextKey, parsedJWS)
return test{
linker: acme.NewLinker("test.ca.smallstep.com", "acme"),
db: &acme.MockDB{
MockGetAccount: func(ctx context.Context, id string) (*acme.Account, error) {
assert.Equals(t, id, accID)
return acc, nil
},
},
ctx: ctx,
next: func(w http.ResponseWriter, r *http.Request) {
_acc, err := accountFromContext(r.Context())
assert.FatalError(t, err)
assert.Equals(t, _acc, acc)
_jwk, err := jwkFromContext(r.Context())
assert.FatalError(t, err)
assert.Equals(t, _jwk, jwk)
w.Write(testBody)
},
statusCode: http.StatusUnauthorized,
err: acme.NewError(acme.ErrorUnauthorizedType,
"account provisioner does not match requested provisioner; account provisioner = %s, requested provisioner = %s",
acc.ProvisionerID, p.GetID()),
}
},
"ok/account-with-location-prefix": func(t *testing.T) test {
acc := &acme.Account{LocationPrefix: prefix + accID, Status: "valid", Key: jwk, ProvisionerName: prov.GetName()}
ctx := acme.NewProvisionerContext(context.Background(), prov)
ctx = context.WithValue(ctx, jwsContextKey, parsedJWS)
return test{
linker: acme.NewLinker("test.ca.smallstep.com", "acme"),
db: &acme.MockDB{
MockGetAccount: func(ctx context.Context, id string) (*acme.Account, error) {
assert.Equals(t, id, accID)
return acc, nil
},
},
ctx: ctx,
next: func(w http.ResponseWriter, r *http.Request) {
_acc, err := accountFromContext(r.Context())
assert.FatalError(t, err)
assert.Equals(t, _acc, acc)
_jwk, err := jwkFromContext(r.Context())
assert.FatalError(t, err)
assert.Equals(t, _jwk, jwk)
w.Write(testBody)
},
statusCode: http.StatusOK,
}
},
"ok/account-without-location-prefix": func(t *testing.T) test {
acc := &acme.Account{Status: "valid", Key: jwk}
ctx := acme.NewProvisionerContext(context.Background(), prov)
ctx = context.WithValue(ctx, jwsContextKey, parsedJWS)
@ -785,12 +915,38 @@ func TestHandler_lookupJWK(t *testing.T) {
statusCode: 200,
}
},
"ok/account-with-provisioner-id": func(t *testing.T) test {
p := newProvWithID()
acc := &acme.Account{LocationPrefix: prefix + accID, Status: "valid", Key: jwk, ProvisionerID: p.GetID()}
ctx := acme.NewProvisionerContext(context.Background(), p)
ctx = context.WithValue(ctx, jwsContextKey, parsedJWS)
return test{
linker: acme.NewLinker("test.ca.smallstep.com", "acme"),
db: &acme.MockDB{
MockGetAccount: func(ctx context.Context, id string) (*acme.Account, error) {
assert.Equals(t, id, accID)
return acc, nil
},
},
ctx: ctx,
next: func(w http.ResponseWriter, r *http.Request) {
_acc, err := accountFromContext(r.Context())
assert.FatalError(t, err)
assert.Equals(t, _acc, acc)
_jwk, err := jwkFromContext(r.Context())
assert.FatalError(t, err)
assert.Equals(t, _jwk, jwk)
w.Write(testBody)
},
statusCode: 200,
}
},
}
for name, run := range tests {
tc := run(t)
t.Run(name, func(t *testing.T) {
ctx := newBaseContext(tc.ctx, tc.db, tc.linker)
req := httptest.NewRequest("GET", u, nil)
req := httptest.NewRequest("GET", u, http.NoBody)
req = req.WithContext(ctx)
w := httptest.NewRecorder()
lookupJWK(tc.next)(w, req)
@ -808,7 +964,6 @@ func TestHandler_lookupJWK(t *testing.T) {
assert.Equals(t, ae.Type, tc.err.Type)
assert.Equals(t, ae.Detail, tc.err.Detail)
assert.Equals(t, ae.Identifier, tc.err.Identifier)
assert.Equals(t, ae.Subproblems, tc.err.Subproblems)
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
} else {
@ -990,7 +1145,7 @@ func TestHandler_extractJWK(t *testing.T) {
tc := run(t)
t.Run(name, func(t *testing.T) {
ctx := newBaseContext(tc.ctx, tc.db)
req := httptest.NewRequest("GET", u, nil)
req := httptest.NewRequest("GET", u, http.NoBody)
req = req.WithContext(ctx)
w := httptest.NewRecorder()
extractJWK(tc.next)(w, req)
@ -1008,7 +1163,6 @@ func TestHandler_extractJWK(t *testing.T) {
assert.Equals(t, ae.Type, tc.err.Type)
assert.Equals(t, ae.Detail, tc.err.Detail)
assert.Equals(t, ae.Identifier, tc.err.Identifier)
assert.Equals(t, ae.Subproblems, tc.err.Subproblems)
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
} else {
@ -1366,7 +1520,7 @@ func TestHandler_validateJWS(t *testing.T) {
tc := run(t)
t.Run(name, func(t *testing.T) {
ctx := newBaseContext(tc.ctx, tc.db)
req := httptest.NewRequest("GET", u, nil)
req := httptest.NewRequest("GET", u, http.NoBody)
req = req.WithContext(ctx)
w := httptest.NewRecorder()
validateJWS(tc.next)(w, req)
@ -1384,7 +1538,6 @@ func TestHandler_validateJWS(t *testing.T) {
assert.Equals(t, ae.Type, tc.err.Type)
assert.Equals(t, ae.Detail, tc.err.Detail)
assert.Equals(t, ae.Identifier, tc.err.Identifier)
assert.Equals(t, ae.Subproblems, tc.err.Subproblems)
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
} else {
@ -1549,7 +1702,7 @@ func TestHandler_extractOrLookupJWK(t *testing.T) {
tc := prep(t)
t.Run(name, func(t *testing.T) {
ctx := newBaseContext(tc.ctx, tc.db, tc.linker)
req := httptest.NewRequest("GET", u, nil)
req := httptest.NewRequest("GET", u, http.NoBody)
req = req.WithContext(ctx)
w := httptest.NewRecorder()
extractOrLookupJWK(tc.next)(w, req)
@ -1567,7 +1720,6 @@ func TestHandler_extractOrLookupJWK(t *testing.T) {
assert.Equals(t, ae.Type, tc.err.Type)
assert.Equals(t, ae.Detail, tc.err.Detail)
assert.Equals(t, ae.Identifier, tc.err.Identifier)
assert.Equals(t, ae.Subproblems, tc.err.Subproblems)
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
} else {
@ -1635,7 +1787,7 @@ func TestHandler_checkPrerequisites(t *testing.T) {
tc := run(t)
t.Run(name, func(t *testing.T) {
ctx := acme.NewPrerequisitesCheckerContext(tc.ctx, tc.prerequisitesChecker)
req := httptest.NewRequest("GET", u, nil)
req := httptest.NewRequest("GET", u, http.NoBody)
req = req.WithContext(ctx)
w := httptest.NewRecorder()
checkPrerequisites(tc.next)(w, req)
@ -1652,7 +1804,6 @@ func TestHandler_checkPrerequisites(t *testing.T) {
assert.FatalError(t, json.Unmarshal(bytes.TrimSpace(body), &ae))
assert.Equals(t, ae.Type, tc.err.Type)
assert.Equals(t, ae.Detail, tc.err.Detail)
assert.Equals(t, ae.Identifier, tc.err.Identifier)
assert.Equals(t, ae.Subproblems, tc.err.Subproblems)
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
} else {
@ -1661,3 +1812,86 @@ func TestHandler_checkPrerequisites(t *testing.T) {
})
}
}
func Test_retryVerificationWithPatchedSignatures(t *testing.T) {
patchedRKey := []byte(`{
"kid": "uioinbiTlJICL0MYsb6ar1totfRA2tiPqWgntF8xUdo",
"crv": "P-256",
"alg": "ES256",
"kty": "EC",
"x": "wlz-Kv9X0h32fzLq-cogls9HxoZQqV-GuWxdb2MCeUY",
"y": "xzP6zRrg_jynYljZTxfJuql_QWtdQR6lpJ52q_6Vavg"
}`)
patchedRJWK := &jose.JSONWebKey{}
err := json.Unmarshal(patchedRKey, patchedRJWK)
require.NoError(t, err)
patchedRBody := `{"payload":"dGVzdC0xMTA1","protected":"eyJhbGciOiJFUzI1NiJ9","signature":"rQPYKYflfKnlgBKqDeWsJH2TJ6iHAnou7sFzXlmYD4ArXqLfYuqotWERKrna2wfzh0pu7USWO2gzlOqRK9qq"}`
patchedR, err := jose.ParseJWS(patchedRBody)
require.NoError(t, err)
patchedSKey := []byte(`{
"kid": "PblXsnK59uTiF5k3mmAN2B6HDPPxqBL_4UGhEG8ZO6g",
"crv": "P-256",
"alg": "ES256",
"kty": "EC",
"x": "T5aM_TOSattXNeUkH1VHZXh8URzdjZTI2zLvVgI0cy0",
"y": "Lf8h8qZnURXIxm6OnQ69kxGC91YtTZRD2GAroEf1UA8"
}`)
patchedSJWK := &jose.JSONWebKey{}
err = json.Unmarshal(patchedSKey, patchedSJWK)
require.NoError(t, err)
patchedSBody := `{"payload":"dGVzdC02Ng","protected":"eyJhbGciOiJFUzI1NiJ9","signature":"krtSKSgVB04oqx6i9QLeal_wZSnjV1_PSIM3AubT0WRIxnhl_yYbVpa3i53p3dUW56TtP6_SUZboH6SvLHMz"}`
patchedS, err := jose.ParseJWS(patchedSBody)
require.NoError(t, err)
patchedRSKey := []byte(`{
"kid": "U8BmBVbZsNUawvhOomJQPa6uYj1rdxCPQWF_nOLVsc4",
"crv": "P-256",
"alg": "ES256",
"kty": "EC",
"x": "Ym0l3GMS6aHBLo-xe73Kub4kafnOBu_QAfOsx5y-bV0",
"y": "wKijX9Cu67HbK94StPcI18WulgRfIMbP2ZU7gQuf3-M"
}`)
patchedRSJWK := &jose.JSONWebKey{}
err = json.Unmarshal(patchedRSKey, patchedRSJWK)
require.NoError(t, err)
patchedRSBody := `{"payload":"dGVzdC05MDY3","protected":"eyJhbGciOiJFUzI1NiJ9","signature":"2r_My19oRg7mWf9I5JTkNYp8otfEMz-yXRA8ltZTAKZxyJLurpVEgicmNItu7lfcCrGrTgI3Obye_gSaIyc"}`
patchedRS, err := jose.ParseJWS(patchedRSBody)
require.NoError(t, err)
patchedRWithWrongJWK, err := jose.ParseJWS(patchedRBody)
require.NoError(t, err)
tests := []struct {
name string
jws *jose.JSONWebSignature
jwk *jose.JSONWebKey
expectedData []byte
expectedSignature string
expectedError error
}{
{"ok/patched-r", patchedR, patchedRJWK, []byte(`test-1105`), `AK0D2CmH5Xyp5YASqg3lrCR9kyeohwJ6Lu7Bc15ZmA-AK16i32LqqLVhESq52tsH84dKbu1EljtoM5TqkSvaqg`, nil},
{"ok/patched-s", patchedS, patchedSJWK, []byte(`test-66`), `krtSKSgVB04oqx6i9QLeal_wZSnjV1_PSIM3AubT0WQASMZ4Zf8mG1aWt4ud6d3VFuek7T-v0lGW6B-kryxzMw`, nil},
{"ok/patched-rs", patchedRS, patchedRSJWK, []byte(`test-9067`), `ANq_zMtfaEYO5ln_SOSU5DWKfKLXxDM_sl0QPJbWUwAApnHIku6ulUSCJyY0i27uV9wKsatOAjc5vJ7-BJojJw`, nil},
{"fail/patched-r-wrong-jwk", patchedRWithWrongJWK, patchedRSJWK, nil, `rQPYKYflfKnlgBKqDeWsJH2TJ6iHAnou7sFzXlmYD4ArXqLfYuqotWERKrna2wfzh0pu7USWO2gzlOqRK9qq`, errors.New("go-jose/go-jose: error in cryptographic primitive")},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
expectedSignature, decodeErr := base64.RawURLEncoding.DecodeString(tt.expectedSignature)
require.NoError(t, decodeErr)
data, err := retryVerificationWithPatchedSignatures(tt.jws, tt.jwk)
if tt.expectedError != nil {
tassert.EqualError(t, err, tt.expectedError.Error())
tassert.Equal(t, expectedSignature, tt.jws.Signatures[0].Signature)
tassert.Empty(t, data)
return
}
tassert.NoError(t, err)
tassert.Len(t, tt.jws.Signatures[0].Signature, 64)
tassert.Equal(t, expectedSignature, tt.jws.Signatures[0].Signature)
tassert.Equal(t, tt.expectedData, data)
})
}
}

@ -10,7 +10,7 @@ import (
"strings"
"time"
"github.com/go-chi/chi"
"github.com/go-chi/chi/v5"
"go.step.sm/crypto/randutil"
"go.step.sm/crypto/x509util"
@ -99,29 +99,29 @@ func NewOrder(w http.ResponseWriter, r *http.Request) {
acc, err := accountFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
prov, err := provisionerFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
payload, err := payloadFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
var nor NewOrderRequest
if err := json.Unmarshal(payload.value, &nor); err != nil {
render.Error(w, acme.WrapError(acme.ErrorMalformedType, err,
render.Error(w, r, acme.WrapError(acme.ErrorMalformedType, err,
"failed to unmarshal new-order request payload"))
return
}
if err := nor.Validate(); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
@ -130,39 +130,39 @@ func NewOrder(w http.ResponseWriter, r *http.Request) {
acmeProv, err := acmeProvisionerFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
var eak *acme.ExternalAccountKey
if acmeProv.RequireEAB {
if eak, err = db.GetExternalAccountKeyByAccountID(ctx, prov.GetID(), acc.ID); err != nil {
render.Error(w, acme.WrapErrorISE(err, "error retrieving external account binding key"))
render.Error(w, r, acme.WrapErrorISE(err, "error retrieving external account binding key"))
return
}
}
acmePolicy, err := newACMEPolicyEngine(eak)
if err != nil {
render.Error(w, acme.WrapErrorISE(err, "error creating ACME policy engine"))
render.Error(w, r, acme.WrapErrorISE(err, "error creating ACME policy engine"))
return
}
for _, identifier := range nor.Identifiers {
// evaluate the ACME account level policy
if err = isIdentifierAllowed(acmePolicy, identifier); err != nil {
render.Error(w, acme.WrapError(acme.ErrorRejectedIdentifierType, err, "not authorized"))
render.Error(w, r, acme.WrapError(acme.ErrorRejectedIdentifierType, err, "not authorized"))
return
}
// evaluate the provisioner level policy
orderIdentifier := provisioner.ACMEIdentifier{Type: provisioner.ACMEIdentifierType(identifier.Type), Value: identifier.Value}
if err = prov.AuthorizeOrderIdentifier(ctx, orderIdentifier); err != nil {
render.Error(w, acme.WrapError(acme.ErrorRejectedIdentifierType, err, "not authorized"))
render.Error(w, r, acme.WrapError(acme.ErrorRejectedIdentifierType, err, "not authorized"))
return
}
// evaluate the authority level policy
if err = ca.AreSANsAllowed(ctx, []string{identifier.Value}); err != nil {
render.Error(w, acme.WrapError(acme.ErrorRejectedIdentifierType, err, "not authorized"))
render.Error(w, r, acme.WrapError(acme.ErrorRejectedIdentifierType, err, "not authorized"))
return
}
}
@ -188,7 +188,7 @@ func NewOrder(w http.ResponseWriter, r *http.Request) {
Status: acme.StatusPending,
}
if err := newAuthorization(ctx, az); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
o.AuthorizationIDs[i] = az.ID
@ -207,14 +207,14 @@ func NewOrder(w http.ResponseWriter, r *http.Request) {
}
if err := db.CreateOrder(ctx, o); err != nil {
render.Error(w, acme.WrapErrorISE(err, "error creating order"))
render.Error(w, r, acme.WrapErrorISE(err, "error creating order"))
return
}
linker.LinkOrder(ctx, o)
w.Header().Set("Location", linker.GetLink(ctx, acme.OrderLinkType, o.ID))
render.JSONStatus(w, o, http.StatusCreated)
render.JSONStatus(w, r, o, http.StatusCreated)
}
func isIdentifierAllowed(acmePolicy policy.X509Policy, identifier acme.Identifier) error {
@ -226,6 +226,7 @@ func isIdentifierAllowed(acmePolicy policy.X509Policy, identifier acme.Identifie
func newACMEPolicyEngine(eak *acme.ExternalAccountKey) (policy.X509Policy, error) {
if eak == nil {
//nolint:nilnil,nolintlint // expected values
return nil, nil
}
return policy.NewX509PolicyEngine(eak.Policy)
@ -288,39 +289,39 @@ func GetOrder(w http.ResponseWriter, r *http.Request) {
acc, err := accountFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
prov, err := provisionerFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
o, err := db.GetOrder(ctx, chi.URLParam(r, "ordID"))
if err != nil {
render.Error(w, acme.WrapErrorISE(err, "error retrieving order"))
render.Error(w, r, acme.WrapErrorISE(err, "error retrieving order"))
return
}
if acc.ID != o.AccountID {
render.Error(w, acme.NewError(acme.ErrorUnauthorizedType,
render.Error(w, r, acme.NewError(acme.ErrorUnauthorizedType,
"account '%s' does not own order '%s'", acc.ID, o.ID))
return
}
if prov.GetID() != o.ProvisionerID {
render.Error(w, acme.NewError(acme.ErrorUnauthorizedType,
render.Error(w, r, acme.NewError(acme.ErrorUnauthorizedType,
"provisioner '%s' does not own order '%s'", prov.GetID(), o.ID))
return
}
if err = o.UpdateStatus(ctx, db); err != nil {
render.Error(w, acme.WrapErrorISE(err, "error updating order status"))
render.Error(w, r, acme.WrapErrorISE(err, "error updating order status"))
return
}
linker.LinkOrder(ctx, o)
w.Header().Set("Location", linker.GetLink(ctx, acme.OrderLinkType, o.ID))
render.JSON(w, o)
render.JSON(w, r, o)
}
// FinalizeOrder attempts to finalize an order and create a certificate.
@ -331,56 +332,56 @@ func FinalizeOrder(w http.ResponseWriter, r *http.Request) {
acc, err := accountFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
prov, err := provisionerFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
payload, err := payloadFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
var fr FinalizeRequest
if err := json.Unmarshal(payload.value, &fr); err != nil {
render.Error(w, acme.WrapError(acme.ErrorMalformedType, err,
render.Error(w, r, acme.WrapError(acme.ErrorMalformedType, err,
"failed to unmarshal finalize-order request payload"))
return
}
if err := fr.Validate(); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
o, err := db.GetOrder(ctx, chi.URLParam(r, "ordID"))
if err != nil {
render.Error(w, acme.WrapErrorISE(err, "error retrieving order"))
render.Error(w, r, acme.WrapErrorISE(err, "error retrieving order"))
return
}
if acc.ID != o.AccountID {
render.Error(w, acme.NewError(acme.ErrorUnauthorizedType,
render.Error(w, r, acme.NewError(acme.ErrorUnauthorizedType,
"account '%s' does not own order '%s'", acc.ID, o.ID))
return
}
if prov.GetID() != o.ProvisionerID {
render.Error(w, acme.NewError(acme.ErrorUnauthorizedType,
render.Error(w, r, acme.NewError(acme.ErrorUnauthorizedType,
"provisioner '%s' does not own order '%s'", prov.GetID(), o.ID))
return
}
ca := mustAuthority(ctx)
if err = o.Finalize(ctx, db, fr.csr, ca, prov); err != nil {
render.Error(w, acme.WrapErrorISE(err, "error finalizing order"))
render.Error(w, r, acme.WrapErrorISE(err, "error finalizing order"))
return
}
linker.LinkOrder(ctx, o)
w.Header().Set("Location", linker.GetLink(ctx, acme.OrderLinkType, o.ID))
render.JSON(w, o)
render.JSON(w, r, o)
}
// challengeTypes determines the types of challenges that should be used

@ -8,13 +8,14 @@ import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/http/httptest"
"net/url"
"reflect"
"testing"
"time"
"github.com/go-chi/chi"
"github.com/go-chi/chi/v5"
"github.com/pkg/errors"
"go.step.sm/crypto/pemutil"
@ -468,7 +469,7 @@ func TestHandler_GetOrder(t *testing.T) {
tc := run(t)
t.Run(name, func(t *testing.T) {
ctx := newBaseContext(tc.ctx, tc.db, acme.NewLinker("test.ca.smallstep.com", "acme"))
req := httptest.NewRequest("GET", u, nil)
req := httptest.NewRequest("GET", u, http.NoBody)
req = req.WithContext(ctx)
w := httptest.NewRecorder()
GetOrder(w, req)
@ -486,7 +487,6 @@ func TestHandler_GetOrder(t *testing.T) {
assert.Equals(t, ae.Type, tc.err.Type)
assert.Equals(t, ae.Detail, tc.err.Detail)
assert.Equals(t, ae.Identifier, tc.err.Identifier)
assert.Equals(t, ae.Subproblems, tc.err.Subproblems)
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
} else {
@ -1828,7 +1828,7 @@ func TestHandler_NewOrder(t *testing.T) {
t.Run(name, func(t *testing.T) {
mockMustAuthority(t, tc.ca)
ctx := newBaseContext(tc.ctx, tc.db, acme.NewLinker("test.ca.smallstep.com", "acme"))
req := httptest.NewRequest("GET", u, nil)
req := httptest.NewRequest("GET", u, http.NoBody)
req = req.WithContext(ctx)
w := httptest.NewRecorder()
NewOrder(w, req)
@ -1846,7 +1846,6 @@ func TestHandler_NewOrder(t *testing.T) {
assert.Equals(t, ae.Type, tc.err.Type)
assert.Equals(t, ae.Detail, tc.err.Detail)
assert.Equals(t, ae.Identifier, tc.err.Identifier)
assert.Equals(t, ae.Subproblems, tc.err.Subproblems)
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
} else {
@ -2126,7 +2125,7 @@ func TestHandler_FinalizeOrder(t *testing.T) {
tc := run(t)
t.Run(name, func(t *testing.T) {
ctx := newBaseContext(tc.ctx, tc.db, acme.NewLinker("test.ca.smallstep.com", "acme"))
req := httptest.NewRequest("GET", u, nil)
req := httptest.NewRequest("GET", u, http.NoBody)
req = req.WithContext(ctx)
w := httptest.NewRecorder()
FinalizeOrder(w, req)
@ -2144,7 +2143,6 @@ func TestHandler_FinalizeOrder(t *testing.T) {
assert.Equals(t, ae.Type, tc.err.Type)
assert.Equals(t, ae.Detail, tc.err.Detail)
assert.Equals(t, ae.Identifier, tc.err.Identifier)
assert.Equals(t, ae.Subproblems, tc.err.Subproblems)
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
} else {

@ -33,65 +33,65 @@ func RevokeCert(w http.ResponseWriter, r *http.Request) {
jws, err := jwsFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
prov, err := provisionerFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
payload, err := payloadFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
var p revokePayload
err = json.Unmarshal(payload.value, &p)
if err != nil {
render.Error(w, acme.WrapErrorISE(err, "error unmarshaling payload"))
render.Error(w, r, acme.WrapErrorISE(err, "error unmarshaling payload"))
return
}
certBytes, err := base64.RawURLEncoding.DecodeString(p.Certificate)
if err != nil {
// in this case the most likely cause is a client that didn't properly encode the certificate
render.Error(w, acme.WrapError(acme.ErrorMalformedType, err, "error base64url decoding payload certificate property"))
render.Error(w, r, acme.WrapError(acme.ErrorMalformedType, err, "error base64url decoding payload certificate property"))
return
}
certToBeRevoked, err := x509.ParseCertificate(certBytes)
if err != nil {
// in this case a client may have encoded something different than a certificate
render.Error(w, acme.WrapError(acme.ErrorMalformedType, err, "error parsing certificate"))
render.Error(w, r, acme.WrapError(acme.ErrorMalformedType, err, "error parsing certificate"))
return
}
serial := certToBeRevoked.SerialNumber.String()
dbCert, err := db.GetCertificateBySerial(ctx, serial)
if err != nil {
render.Error(w, acme.WrapErrorISE(err, "error retrieving certificate by serial"))
render.Error(w, r, acme.WrapErrorISE(err, "error retrieving certificate by serial"))
return
}
if !bytes.Equal(dbCert.Leaf.Raw, certToBeRevoked.Raw) {
// this should never happen
render.Error(w, acme.NewErrorISE("certificate raw bytes are not equal"))
render.Error(w, r, acme.NewErrorISE("certificate raw bytes are not equal"))
return
}
if shouldCheckAccountFrom(jws) {
account, err := accountFromContext(ctx)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
acmeErr := isAccountAuthorized(ctx, dbCert, certToBeRevoked, account)
if acmeErr != nil {
render.Error(w, acmeErr)
render.Error(w, r, acmeErr)
return
}
} else {
@ -100,7 +100,7 @@ func RevokeCert(w http.ResponseWriter, r *http.Request) {
_, err := jws.Verify(certToBeRevoked.PublicKey)
if err != nil {
// TODO(hs): possible to determine an error vs. unauthorized and thus provide an ISE vs. Unauthorized?
render.Error(w, wrapUnauthorizedError(certToBeRevoked, nil, "verification of jws using certificate public key failed", err))
render.Error(w, r, wrapUnauthorizedError(certToBeRevoked, nil, "verification of jws using certificate public key failed", err))
return
}
}
@ -108,19 +108,19 @@ func RevokeCert(w http.ResponseWriter, r *http.Request) {
ca := mustAuthority(ctx)
hasBeenRevokedBefore, err := ca.IsRevoked(serial)
if err != nil {
render.Error(w, acme.WrapErrorISE(err, "error retrieving revocation status of certificate"))
render.Error(w, r, acme.WrapErrorISE(err, "error retrieving revocation status of certificate"))
return
}
if hasBeenRevokedBefore {
render.Error(w, acme.NewError(acme.ErrorAlreadyRevokedType, "certificate was already revoked"))
render.Error(w, r, acme.NewError(acme.ErrorAlreadyRevokedType, "certificate was already revoked"))
return
}
reasonCode := p.ReasonCode
acmeErr := validateReasonCode(reasonCode)
if acmeErr != nil {
render.Error(w, acmeErr)
render.Error(w, r, acmeErr)
return
}
@ -128,14 +128,14 @@ func RevokeCert(w http.ResponseWriter, r *http.Request) {
ctx = provisioner.NewContextWithMethod(ctx, provisioner.RevokeMethod)
err = prov.AuthorizeRevoke(ctx, "")
if err != nil {
render.Error(w, acme.WrapErrorISE(err, "error authorizing revocation on provisioner"))
render.Error(w, r, acme.WrapErrorISE(err, "error authorizing revocation on provisioner"))
return
}
options := revokeOptions(serial, certToBeRevoked, reasonCode)
err = ca.Revoke(ctx, options)
if err != nil {
render.Error(w, wrapRevokeErr(err))
render.Error(w, r, wrapRevokeErr(err))
return
}
@ -151,7 +151,7 @@ func RevokeCert(w http.ResponseWriter, r *http.Request) {
// the identifiers in the certificate are extracted and compared against the (valid) Authorizations
// that are stored for the ACME Account. If these sets match, the Account is considered authorized
// to revoke the certificate. If this check fails, the client will receive an unauthorized error.
func isAccountAuthorized(ctx context.Context, dbCert *acme.Certificate, certToBeRevoked *x509.Certificate, account *acme.Account) *acme.Error {
func isAccountAuthorized(_ context.Context, dbCert *acme.Certificate, certToBeRevoked *x509.Certificate, account *acme.Account) *acme.Error {
if !account.IsValid() {
return wrapUnauthorizedError(certToBeRevoked, nil, fmt.Sprintf("account '%s' has status '%s'", account.ID, account.Status), nil)
}

@ -21,7 +21,7 @@ import (
"testing"
"time"
"github.com/go-chi/chi"
"github.com/go-chi/chi/v5"
"github.com/google/go-cmp/cmp"
"github.com/pkg/errors"
"golang.org/x/crypto/ocsp"
@ -258,7 +258,7 @@ func jwkEncode(pub crypto.PublicKey) (string, error) {
// jwsFinal constructs the final JWS object.
// Implementation taken from github.com/mholt/acmez, which seems to be based on
// https://github.com/golang/crypto/blob/master/acme/jws.go.
func jwsFinal(sha crypto.Hash, sig []byte, phead, payload string) ([]byte, error) {
func jwsFinal(_ crypto.Hash, sig []byte, phead, payload string) ([]byte, error) {
enc := struct {
Protected string `json:"protected"`
Payload string `json:"payload"`
@ -281,7 +281,7 @@ type mockCA struct {
MockAreSANsallowed func(ctx context.Context, sans []string) error
}
func (m *mockCA) Sign(cr *x509.CertificateRequest, opts provisioner.SignOptions, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
func (m *mockCA) SignWithContext(context.Context, *x509.CertificateRequest, provisioner.SignOptions, ...provisioner.SignOption) ([]*x509.Certificate, error) {
return nil, nil
}
@ -1072,7 +1072,7 @@ func TestHandler_RevokeCert(t *testing.T) {
t.Run(name, func(t *testing.T) {
ctx := newBaseContext(tc.ctx, tc.db, acme.NewLinker("test.ca.smallstep.com", "acme"))
mockMustAuthority(t, tc.ca)
req := httptest.NewRequest("POST", revokeURL, nil)
req := httptest.NewRequest("POST", revokeURL, http.NoBody)
req = req.WithContext(ctx)
w := httptest.NewRecorder()
RevokeCert(w, req)
@ -1090,12 +1090,11 @@ func TestHandler_RevokeCert(t *testing.T) {
assert.Equals(t, ae.Type, tc.err.Type)
assert.Equals(t, ae.Detail, tc.err.Detail)
assert.Equals(t, ae.Identifier, tc.err.Identifier)
assert.Equals(t, ae.Subproblems, tc.err.Subproblems)
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
} else {
assert.True(t, bytes.Equal(bytes.TrimSpace(body), []byte{}))
assert.Equals(t, int64(0), req.ContentLength)
assert.Equals(t, int64(-1), req.ContentLength)
assert.Equals(t, []string{fmt.Sprintf("<%s/acme/%s/directory>;rel=\"index\"", baseURL.String(), escProvName)}, res.Header["Link"])
}
})
@ -1230,7 +1229,6 @@ func TestHandler_isAccountAuthorized(t *testing.T) {
assert.Equals(t, acmeErr.Type, tc.err.Type)
assert.Equals(t, acmeErr.Status, tc.err.Status)
assert.Equals(t, acmeErr.Detail, tc.err.Detail)
assert.Equals(t, acmeErr.Identifier, tc.err.Identifier)
assert.Equals(t, acmeErr.Subproblems, tc.err.Subproblems)
})
@ -1281,7 +1279,7 @@ func Test_wrapUnauthorizedError(t *testing.T) {
}
},
"wrap-subject": func(t *testing.T) test {
acmeErr := acme.NewError(acme.ErrorUnauthorizedType, "verification of jws using certificate public key failed: square/go-jose: error in cryptographic primitive")
acmeErr := acme.NewError(acme.ErrorUnauthorizedType, "verification of jws using certificate public key failed: go-jose/go-jose: error in cryptographic primitive")
acmeErr.Status = http.StatusForbidden
acmeErr.Detail = "No authorization provided for name test.example.com"
cert := &x509.Certificate{
@ -1290,7 +1288,7 @@ func Test_wrapUnauthorizedError(t *testing.T) {
},
}
return test{
err: errors.New("square/go-jose: error in cryptographic primitive"),
err: errors.New("go-jose/go-jose: error in cryptographic primitive"),
cert: cert,
unauthorizedIdentifiers: []acme.Identifier{},
msg: "verification of jws using certificate public key failed",
@ -1323,7 +1321,6 @@ func Test_wrapUnauthorizedError(t *testing.T) {
assert.Equals(t, acmeErr.Type, tc.want.Type)
assert.Equals(t, acmeErr.Status, tc.want.Status)
assert.Equals(t, acmeErr.Detail, tc.want.Detail)
assert.Equals(t, acmeErr.Identifier, tc.want.Identifier)
assert.Equals(t, acmeErr.Subproblems, tc.want.Subproblems)
})
}

@ -8,15 +8,16 @@ import (
// Authorization representst an ACME Authorization.
type Authorization struct {
ID string `json:"-"`
AccountID string `json:"-"`
Token string `json:"-"`
Identifier Identifier `json:"identifier"`
Status Status `json:"status"`
Challenges []*Challenge `json:"challenges"`
Wildcard bool `json:"wildcard"`
ExpiresAt time.Time `json:"expires"`
Error *Error `json:"error,omitempty"`
ID string `json:"-"`
AccountID string `json:"-"`
Token string `json:"-"`
Fingerprint string `json:"-"`
Identifier Identifier `json:"identifier"`
Status Status `json:"status"`
Challenges []*Challenge `json:"challenges"`
Wildcard bool `json:"wildcard"`
ExpiresAt time.Time `json:"expires"`
Error *Error `json:"error,omitempty"`
}
// ToLog enables response logging.

@ -26,9 +26,17 @@ import (
"time"
"github.com/fxamacker/cbor/v2"
"github.com/smallstep/certificates/authority/provisioner"
"github.com/google/go-tpm/legacy/tpm2"
"golang.org/x/exp/slices"
"github.com/smallstep/go-attestation/attest"
"go.step.sm/crypto/jose"
"go.step.sm/crypto/keyutil"
"go.step.sm/crypto/pemutil"
"go.step.sm/crypto/x509util"
"github.com/smallstep/certificates/authority/provisioner"
)
type ChallengeType string
@ -44,6 +52,18 @@ const (
DEVICEATTEST01 ChallengeType = "device-attest-01"
)
var (
// InsecurePortHTTP01 is the port used to verify http-01 challenges. If not set it
// defaults to 80.
InsecurePortHTTP01 int
// InsecurePortTLSALPN01 is the port used to verify tls-alpn-01 challenges. If not
// set it defaults to 443.
//
// This variable can be used for testing purposes.
InsecurePortTLSALPN01 int
)
// Challenge represents an ACME response Challenge type.
type Challenge struct {
ID string `json:"-"`
@ -67,10 +87,9 @@ func (ch *Challenge) ToLog() (interface{}, error) {
return string(b), nil
}
// Validate attempts to validate the challenge. Stores changes to the Challenge
// type using the DB interface.
// satisfactorily validated, the 'status' and 'validated' attributes are
// updated.
// Validate attempts to validate the Challenge. Stores changes to the Challenge
// type using the DB interface. If the Challenge is validated, the 'status' and
// 'validated' attributes are updated.
func (ch *Challenge) Validate(ctx context.Context, db DB, jwk *jose.JSONWebKey, payload []byte) error {
// If already valid or invalid then return without performing validation.
if ch.Status != StatusPending {
@ -93,6 +112,12 @@ func (ch *Challenge) Validate(ctx context.Context, db DB, jwk *jose.JSONWebKey,
func http01Validate(ctx context.Context, ch *Challenge, db DB, jwk *jose.JSONWebKey) error {
u := &url.URL{Scheme: "http", Host: http01ChallengeHost(ch.Value), Path: fmt.Sprintf("/.well-known/acme-challenge/%s", ch.Token)}
// Append insecure port if set.
// Only used for testing purposes.
if InsecurePortHTTP01 != 0 {
u.Host += ":" + strconv.Itoa(InsecurePortHTTP01)
}
vc := MustClientFromContext(ctx)
resp, err := vc.Get(u.String())
if err != nil {
@ -165,7 +190,14 @@ func tlsalpn01Validate(ctx context.Context, ch *Challenge, db DB, jwk *jose.JSON
InsecureSkipVerify: true, //nolint:gosec // we expect a self-signed challenge certificate
}
hostPort := net.JoinHostPort(ch.Value, "443")
var hostPort string
// Allow to change TLS port for testing purposes.
if port := InsecurePortTLSALPN01; port == 0 {
hostPort = net.JoinHostPort(ch.Value, "443")
} else {
hostPort = net.JoinHostPort(ch.Value, strconv.Itoa(port))
}
vc := MustClientFromContext(ctx)
conn, err := vc.TLSDial("tcp", hostPort, config)
@ -310,20 +342,26 @@ func dns01Validate(ctx context.Context, ch *Challenge, db DB, jwk *jose.JSONWebK
return nil
}
type Payload struct {
type payloadType struct {
AttObj string `json:"attObj"`
Error string `json:"error"`
}
type AttestationObject struct {
type attestationObject struct {
Format string `json:"fmt"`
AttStatement map[string]interface{} `json:"attStmt,omitempty"`
}
// TODO(bweeks): move attestation verification to a shared package.
// TODO(bweeks): define new error type for failed attestation validation.
func deviceAttest01Validate(ctx context.Context, ch *Challenge, db DB, jwk *jose.JSONWebKey, payload []byte) error {
var p Payload
// Load authorization to store the key fingerprint.
az, err := db.GetAuthorization(ctx, ch.AuthorizationID)
if err != nil {
return WrapErrorISE(err, "error loading authorization")
}
// Parse payload.
var p payloadType
if err := json.Unmarshal(payload, &p); err != nil {
return WrapErrorISE(err, "error unmarshalling JSON")
}
@ -337,18 +375,23 @@ func deviceAttest01Validate(ctx context.Context, ch *Challenge, db DB, jwk *jose
return WrapErrorISE(err, "error base64 decoding attObj")
}
att := AttestationObject{}
att := attestationObject{}
if err := cbor.Unmarshal(attObj, &att); err != nil {
return WrapErrorISE(err, "error unmarshalling CBOR")
}
format := att.Format
prov := MustProvisionerFromContext(ctx)
if !prov.IsAttestationFormatEnabled(ctx, provisioner.ACMEAttestationFormat(att.Format)) {
if !prov.IsAttestationFormatEnabled(ctx, provisioner.ACMEAttestationFormat(format)) {
if format != "apple" && format != "step" && format != "tpm" {
return storeError(ctx, db, ch, true, NewDetailedError(ErrorBadAttestationStatementType, "unsupported attestation object format %q", format))
}
return storeError(ctx, db, ch, true,
NewError(ErrorBadAttestationStatementType, "attestation format %q is not enabled", att.Format))
NewError(ErrorBadAttestationStatementType, "attestation format %q is not enabled", format))
}
switch att.Format {
switch format {
case "apple":
data, err := doAppleAttestationFormat(ctx, prov, ch, &att)
if err != nil {
@ -366,7 +409,7 @@ func deviceAttest01Validate(ctx context.Context, ch *Challenge, db DB, jwk *jose
if len(data.Nonce) != 0 {
sum := sha256.Sum256([]byte(ch.Token))
if subtle.ConstantTimeCompare(data.Nonce, sum[:]) != 1 {
return storeError(ctx, db, ch, true, NewError(ErrorBadAttestationStatementType, "challenge token does not match"))
return storeError(ctx, db, ch, true, NewDetailedError(ErrorBadAttestationStatementType, "challenge token does not match"))
}
}
@ -375,8 +418,16 @@ func deviceAttest01Validate(ctx context.Context, ch *Challenge, db DB, jwk *jose
//
// Note: We might want to use an external service for this.
if data.UDID != ch.Value && data.SerialNumber != ch.Value {
return storeError(ctx, db, ch, true, NewError(ErrorBadAttestationStatementType, "permanent identifier does not match"))
subproblem := NewSubproblemWithIdentifier(
ErrorRejectedIdentifierType,
Identifier{Type: "permanent-identifier", Value: ch.Value},
"challenge identifier %q doesn't match any of the attested hardware identifiers %q", ch.Value, []string{data.UDID, data.SerialNumber},
)
return storeError(ctx, db, ch, true, NewDetailedError(ErrorBadAttestationStatementType, "permanent identifier does not match").AddSubproblems(subproblem))
}
// Update attestation key fingerprint to compare against the CSR
az.Fingerprint = data.Fingerprint
case "step":
data, err := doStepAttestationFormat(ctx, prov, ch, jwk, &att)
if err != nil {
@ -390,15 +441,53 @@ func deviceAttest01Validate(ctx context.Context, ch *Challenge, db DB, jwk *jose
return WrapErrorISE(err, "error validating attestation")
}
// Validate Apple's ClientIdentifier (Identifier.Value) with device
// identifiers.
// Validate the YubiKey serial number from the attestation
// certificate with the challenged Order value.
//
// Note: We might want to use an external service for this.
if data.SerialNumber != ch.Value {
return storeError(ctx, db, ch, true, NewError(ErrorBadAttestationStatementType, "permanent identifier does not match"))
subproblem := NewSubproblemWithIdentifier(
ErrorRejectedIdentifierType,
Identifier{Type: "permanent-identifier", Value: ch.Value},
"challenge identifier %q doesn't match the attested hardware identifier %q", ch.Value, data.SerialNumber,
)
return storeError(ctx, db, ch, true, NewDetailedError(ErrorBadAttestationStatementType, "permanent identifier does not match").AddSubproblems(subproblem))
}
// Update attestation key fingerprint to compare against the CSR
az.Fingerprint = data.Fingerprint
case "tpm":
data, err := doTPMAttestationFormat(ctx, prov, ch, jwk, &att)
if err != nil {
var acmeError *Error
if errors.As(err, &acmeError) {
if acmeError.Status == 500 {
return acmeError
}
return storeError(ctx, db, ch, true, acmeError)
}
return WrapErrorISE(err, "error validating attestation")
}
// TODO(hs): currently this will allow a request for which no PermanentIdentifiers have been
// extracted from the AK certificate. This is currently the case for AK certs from the CLI, as we
// haven't implemented a way for AK certs requested by the CLI to always contain the requested
// PermanentIdentifier. Omitting the check below doesn't allow just any request, as the Order can
// still fail if the challenge value isn't equal to the CSR subject.
if len(data.PermanentIdentifiers) > 0 && !slices.Contains(data.PermanentIdentifiers, ch.Value) { // TODO(hs): add support for HardwareModuleName
subproblem := NewSubproblemWithIdentifier(
ErrorRejectedIdentifierType,
Identifier{Type: "permanent-identifier", Value: ch.Value},
"challenge identifier %q doesn't match any of the attested hardware identifiers %q", ch.Value, data.PermanentIdentifiers,
)
return storeError(ctx, db, ch, true, NewDetailedError(ErrorBadAttestationStatementType, "permanent identifier does not match").AddSubproblems(subproblem))
}
// Update attestation key fingerprint to compare against the CSR
az.Fingerprint = data.Fingerprint
default:
return storeError(ctx, db, ch, true, NewError(ErrorBadAttestationStatementType, "unexpected attestation object format"))
return storeError(ctx, db, ch, true, NewDetailedError(ErrorBadAttestationStatementType, "unsupported attestation object format %q", format))
}
// Update and store the challenge.
@ -406,12 +495,314 @@ func deviceAttest01Validate(ctx context.Context, ch *Challenge, db DB, jwk *jose
ch.Error = nil
ch.ValidatedAt = clock.Now().Format(time.RFC3339)
// Store the fingerprint in the authorization.
//
// TODO: add method to update authorization and challenge atomically.
if az.Fingerprint != "" {
if err := db.UpdateAuthorization(ctx, az); err != nil {
return WrapErrorISE(err, "error updating authorization")
}
}
if err := db.UpdateChallenge(ctx, ch); err != nil {
return WrapErrorISE(err, "error updating challenge")
}
return nil
}
var (
oidSubjectAlternativeName = asn1.ObjectIdentifier{2, 5, 29, 17}
)
type tpmAttestationData struct {
Certificate *x509.Certificate
VerifiedChains [][]*x509.Certificate
PermanentIdentifiers []string
Fingerprint string
}
// coseAlgorithmIdentifier models a COSEAlgorithmIdentifier.
// Also see https://www.w3.org/TR/webauthn-2/#sctn-alg-identifier.
type coseAlgorithmIdentifier int32
const (
coseAlgES256 coseAlgorithmIdentifier = -7
coseAlgRS256 coseAlgorithmIdentifier = -257
coseAlgRS1 coseAlgorithmIdentifier = -65535 // deprecated, but (still) often used in TPMs
)
func doTPMAttestationFormat(_ context.Context, prov Provisioner, ch *Challenge, jwk *jose.JSONWebKey, att *attestationObject) (*tpmAttestationData, error) {
ver, ok := att.AttStatement["ver"].(string)
if !ok {
return nil, NewDetailedError(ErrorBadAttestationStatementType, "ver not present")
}
if ver != "2.0" {
return nil, NewDetailedError(ErrorBadAttestationStatementType, "version %q is not supported", ver)
}
x5c, ok := att.AttStatement["x5c"].([]interface{})
if !ok {
return nil, NewDetailedError(ErrorBadAttestationStatementType, "x5c not present")
}
if len(x5c) == 0 {
return nil, NewDetailedError(ErrorBadAttestationStatementType, "x5c is empty")
}
akCertBytes, ok := x5c[0].([]byte)
if !ok {
return nil, NewDetailedError(ErrorBadAttestationStatementType, "x5c is malformed")
}
akCert, err := x509.ParseCertificate(akCertBytes)
if err != nil {
return nil, WrapDetailedError(ErrorBadAttestationStatementType, err, "x5c is malformed")
}
intermediates := x509.NewCertPool()
for _, v := range x5c[1:] {
intCertBytes, vok := v.([]byte)
if !vok {
return nil, NewDetailedError(ErrorBadAttestationStatementType, "x5c is malformed")
}
intCert, err := x509.ParseCertificate(intCertBytes)
if err != nil {
return nil, WrapDetailedError(ErrorBadAttestationStatementType, err, "x5c is malformed")
}
intermediates.AddCert(intCert)
}
// TODO(hs): this can be removed when permanent-identifier/hardware-module-name are handled correctly in
// the stdlib in https://cs.opensource.google/go/go/+/refs/tags/go1.19:src/crypto/x509/parser.go;drc=b5b2cf519fe332891c165077f3723ee74932a647;l=362,
// but I doubt that will happen.
if len(akCert.UnhandledCriticalExtensions) > 0 {
unhandledCriticalExtensions := akCert.UnhandledCriticalExtensions[:0]
for _, extOID := range akCert.UnhandledCriticalExtensions {
if !extOID.Equal(oidSubjectAlternativeName) {
// critical extensions other than the Subject Alternative Name remain unhandled
unhandledCriticalExtensions = append(unhandledCriticalExtensions, extOID)
}
}
akCert.UnhandledCriticalExtensions = unhandledCriticalExtensions
}
roots, ok := prov.GetAttestationRoots()
if !ok {
return nil, NewErrorISE("no root CA bundle available to verify the attestation certificate")
}
// verify that the AK certificate was signed by a trusted root,
// chained to by the intermediates provided by the client. As part
// of building the verified certificate chain, the signature over the
// AK certificate is checked to be a valid signature of one of the
// provided intermediates. Signatures over the intermediates are in
// turn also verified to be valid signatures from one of the trusted
// roots.
verifiedChains, err := akCert.Verify(x509.VerifyOptions{
Roots: roots,
Intermediates: intermediates,
CurrentTime: time.Now().Truncate(time.Second),
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
})
if err != nil {
return nil, WrapDetailedError(ErrorBadAttestationStatementType, err, "x5c is not valid")
}
// validate additional AK certificate requirements
if err := validateAKCertificate(akCert); err != nil {
return nil, WrapDetailedError(ErrorBadAttestationStatementType, err, "AK certificate is not valid")
}
// TODO(hs): implement revocation check; Verify() doesn't perform CRL check nor OCSP lookup.
sans, err := x509util.ParseSubjectAlternativeNames(akCert)
if err != nil {
return nil, WrapDetailedError(ErrorBadAttestationStatementType, err, "failed parsing AK certificate Subject Alternative Names")
}
permanentIdentifiers := make([]string, len(sans.PermanentIdentifiers))
for i, pi := range sans.PermanentIdentifiers {
permanentIdentifiers[i] = pi.Identifier
}
// extract and validate pubArea, sig, certInfo and alg properties from the request body
pubArea, ok := att.AttStatement["pubArea"].([]byte)
if !ok {
return nil, NewDetailedError(ErrorBadAttestationStatementType, "invalid pubArea in attestation statement")
}
if len(pubArea) == 0 {
return nil, NewDetailedError(ErrorBadAttestationStatementType, "pubArea is empty")
}
sig, ok := att.AttStatement["sig"].([]byte)
if !ok {
return nil, NewDetailedError(ErrorBadAttestationStatementType, "invalid sig in attestation statement")
}
if len(sig) == 0 {
return nil, NewDetailedError(ErrorBadAttestationStatementType, "sig is empty")
}
certInfo, ok := att.AttStatement["certInfo"].([]byte)
if !ok {
return nil, NewDetailedError(ErrorBadAttestationStatementType, "invalid certInfo in attestation statement")
}
if len(certInfo) == 0 {
return nil, NewDetailedError(ErrorBadAttestationStatementType, "certInfo is empty")
}
alg, ok := att.AttStatement["alg"].(int64)
if !ok {
return nil, NewDetailedError(ErrorBadAttestationStatementType, "invalid alg in attestation statement")
}
var hash crypto.Hash
switch coseAlgorithmIdentifier(alg) {
case coseAlgRS256, coseAlgES256:
hash = crypto.SHA256
case coseAlgRS1:
hash = crypto.SHA1
default:
return nil, NewDetailedError(ErrorBadAttestationStatementType, "invalid alg %d in attestation statement", alg)
}
// recreate the generated key certification parameter values and verify
// the attested key using the public key of the AK.
certificationParameters := &attest.CertificationParameters{
Public: pubArea, // the public key that was attested
CreateAttestation: certInfo, // the attested properties of the key
CreateSignature: sig, // signature over the attested properties
}
verifyOpts := attest.VerifyOpts{
Public: akCert.PublicKey, // public key of the AK that attested the key
Hash: hash,
}
if err = certificationParameters.Verify(verifyOpts); err != nil {
return nil, WrapDetailedError(ErrorBadAttestationStatementType, err, "invalid certification parameters")
}
// decode the "certInfo" data. This won't fail, as it's also done as part of Verify().
tpmCertInfo, err := tpm2.DecodeAttestationData(certInfo)
if err != nil {
return nil, WrapDetailedError(ErrorBadAttestationStatementType, err, "failed decoding attestation data")
}
keyAuth, err := KeyAuthorization(ch.Token, jwk)
if err != nil {
return nil, WrapErrorISE(err, "failed creating key auth digest")
}
hashedKeyAuth := sha256.Sum256([]byte(keyAuth))
// verify the WebAuthn object contains the expect key authorization digest, which is carried
// within the encoded `certInfo` property of the attestation statement.
if subtle.ConstantTimeCompare(hashedKeyAuth[:], []byte(tpmCertInfo.ExtraData)) == 0 {
return nil, NewDetailedError(ErrorBadAttestationStatementType, "key authorization invalid")
}
// decode the (attested) public key and determine its fingerprint. This won't fail, as it's also done as part of Verify().
pub, err := tpm2.DecodePublic(pubArea)
if err != nil {
return nil, WrapDetailedError(ErrorBadAttestationStatementType, err, "failed decoding pubArea")
}
publicKey, err := pub.Key()
if err != nil {
return nil, WrapDetailedError(ErrorBadAttestationStatementType, err, "failed getting public key")
}
data := &tpmAttestationData{
Certificate: akCert,
VerifiedChains: verifiedChains,
PermanentIdentifiers: permanentIdentifiers,
}
if data.Fingerprint, err = keyutil.Fingerprint(publicKey); err != nil {
return nil, WrapErrorISE(err, "error calculating key fingerprint")
}
// TODO(hs): pass more attestation data, so that that can be used/recorded too?
return data, nil
}
var (
oidExtensionExtendedKeyUsage = asn1.ObjectIdentifier{2, 5, 29, 37}
oidTCGKpAIKCertificate = asn1.ObjectIdentifier{2, 23, 133, 8, 3}
)
// validateAKCertificate validates the X.509 AK certificate to be
// in accordance with the required properties. The requirements come from:
// https://www.w3.org/TR/webauthn-2/#sctn-tpm-cert-requirements.
//
// - Version MUST be set to 3.
// - Subject field MUST be set to empty.
// - The Subject Alternative Name extension MUST be set as defined
// in [TPMv2-EK-Profile] section 3.2.9.
// - The Extended Key Usage extension MUST contain the OID 2.23.133.8.3
// ("joint-iso-itu-t(2) international-organizations(23) 133 tcg-kp(8) tcg-kp-AIKCertificate(3)").
// - The Basic Constraints extension MUST have the CA component set to false.
// - An Authority Information Access (AIA) extension with entry id-ad-ocsp
// and a CRL Distribution Point extension [RFC5280] are both OPTIONAL as
// the status of many attestation certificates is available through metadata
// services. See, for example, the FIDO Metadata Service.
func validateAKCertificate(c *x509.Certificate) error {
if c.Version != 3 {
return fmt.Errorf("AK certificate has invalid version %d; only version 3 is allowed", c.Version)
}
if c.Subject.String() != "" {
return fmt.Errorf("AK certificate subject must be empty; got %q", c.Subject)
}
if c.IsCA {
return errors.New("AK certificate must not be a CA")
}
if err := validateAKCertificateExtendedKeyUsage(c); err != nil {
return err
}
return validateAKCertificateSubjectAlternativeNames(c)
}
// validateAKCertificateSubjectAlternativeNames checks if the AK certificate
// has TPM hardware details set.
func validateAKCertificateSubjectAlternativeNames(c *x509.Certificate) error {
sans, err := x509util.ParseSubjectAlternativeNames(c)
if err != nil {
return fmt.Errorf("failed parsing AK certificate Subject Alternative Names: %w", err)
}
details := sans.TPMHardwareDetails
manufacturer, model, version := details.Manufacturer, details.Model, details.Version
switch {
case manufacturer == "":
return errors.New("missing TPM manufacturer")
case model == "":
return errors.New("missing TPM model")
case version == "":
return errors.New("missing TPM version")
}
return nil
}
// validateAKCertificateExtendedKeyUsage checks if the AK certificate
// has the "tcg-kp-AIKCertificate" Extended Key Usage set.
func validateAKCertificateExtendedKeyUsage(c *x509.Certificate) error {
var (
valid = false
ekus []asn1.ObjectIdentifier
)
for _, ext := range c.Extensions {
if ext.Id.Equal(oidExtensionExtendedKeyUsage) {
if _, err := asn1.Unmarshal(ext.Value, &ekus); err != nil || !ekus[0].Equal(oidTCGKpAIKCertificate) {
return errors.New("AK certificate is missing Extended Key Usage value tcg-kp-AIKCertificate (2.23.133.8.3)")
}
valid = true
}
}
if !valid {
return errors.New("AK certificate is missing Extended Key Usage extension")
}
return nil
}
// Apple Enterprise Attestation Root CA from
// https://www.apple.com/certificateauthority/private/
const appleEnterpriseAttestationRootCA = `-----BEGIN CERTIFICATE-----
@ -442,9 +833,10 @@ type appleAttestationData struct {
UDID string
SEPVersion string
Certificate *x509.Certificate
Fingerprint string
}
func doAppleAttestationFormat(ctx context.Context, prov Provisioner, ch *Challenge, att *AttestationObject) (*appleAttestationData, error) {
func doAppleAttestationFormat(_ context.Context, prov Provisioner, _ *Challenge, att *attestationObject) (*appleAttestationData, error) {
// Use configured or default attestation roots if none is configured.
roots, ok := prov.GetAttestationRoots()
if !ok {
@ -458,30 +850,30 @@ func doAppleAttestationFormat(ctx context.Context, prov Provisioner, ch *Challen
x5c, ok := att.AttStatement["x5c"].([]interface{})
if !ok {
return nil, NewError(ErrorBadAttestationStatementType, "x5c not present")
return nil, NewDetailedError(ErrorBadAttestationStatementType, "x5c not present")
}
if len(x5c) == 0 {
return nil, NewError(ErrorRejectedIdentifierType, "x5c is empty")
return nil, NewDetailedError(ErrorBadAttestationStatementType, "x5c is empty")
}
der, ok := x5c[0].([]byte)
if !ok {
return nil, NewError(ErrorBadAttestationStatementType, "x5c is malformed")
return nil, NewDetailedError(ErrorBadAttestationStatementType, "x5c is malformed")
}
leaf, err := x509.ParseCertificate(der)
if err != nil {
return nil, WrapError(ErrorBadAttestationStatementType, err, "x5c is malformed")
return nil, WrapDetailedError(ErrorBadAttestationStatementType, err, "x5c is malformed")
}
intermediates := x509.NewCertPool()
for _, v := range x5c[1:] {
der, ok = v.([]byte)
if !ok {
return nil, NewError(ErrorBadAttestationStatementType, "x5c is malformed")
return nil, NewDetailedError(ErrorBadAttestationStatementType, "x5c is malformed")
}
cert, err := x509.ParseCertificate(der)
if err != nil {
return nil, WrapError(ErrorBadAttestationStatementType, err, "x5c is malformed")
return nil, WrapDetailedError(ErrorBadAttestationStatementType, err, "x5c is malformed")
}
intermediates.AddCert(cert)
}
@ -492,12 +884,15 @@ func doAppleAttestationFormat(ctx context.Context, prov Provisioner, ch *Challen
CurrentTime: time.Now().Truncate(time.Second),
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
}); err != nil {
return nil, WrapError(ErrorBadAttestationStatementType, err, "x5c is not valid")
return nil, WrapDetailedError(ErrorBadAttestationStatementType, err, "x5c is not valid")
}
data := &appleAttestationData{
Certificate: leaf,
}
if data.Fingerprint, err = keyutil.Fingerprint(leaf.PublicKey); err != nil {
return nil, WrapErrorISE(err, "error calculating key fingerprint")
}
for _, ext := range leaf.Extensions {
switch {
case ext.Id.Equal(oidAppleSerialNumber):
@ -543,9 +938,10 @@ var oidYubicoSerialNumber = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 41482, 3, 7}
type stepAttestationData struct {
Certificate *x509.Certificate
SerialNumber string
Fingerprint string
}
func doStepAttestationFormat(ctx context.Context, prov Provisioner, ch *Challenge, jwk *jose.JSONWebKey, att *AttestationObject) (*stepAttestationData, error) {
func doStepAttestationFormat(_ context.Context, prov Provisioner, ch *Challenge, jwk *jose.JSONWebKey, att *attestationObject) (*stepAttestationData, error) {
// Use configured or default attestation roots if none is configured.
roots, ok := prov.GetAttestationRoots()
if !ok {
@ -560,28 +956,28 @@ func doStepAttestationFormat(ctx context.Context, prov Provisioner, ch *Challeng
// Extract x5c and verify certificate
x5c, ok := att.AttStatement["x5c"].([]interface{})
if !ok {
return nil, NewError(ErrorBadAttestationStatementType, "x5c not present")
return nil, NewDetailedError(ErrorBadAttestationStatementType, "x5c not present")
}
if len(x5c) == 0 {
return nil, NewError(ErrorRejectedIdentifierType, "x5c is empty")
return nil, NewDetailedError(ErrorRejectedIdentifierType, "x5c is empty")
}
der, ok := x5c[0].([]byte)
if !ok {
return nil, NewError(ErrorBadAttestationStatementType, "x5c is malformed")
return nil, NewDetailedError(ErrorBadAttestationStatementType, "x5c is malformed")
}
leaf, err := x509.ParseCertificate(der)
if err != nil {
return nil, WrapError(ErrorBadAttestationStatementType, err, "x5c is malformed")
return nil, WrapDetailedError(ErrorBadAttestationStatementType, err, "x5c is malformed")
}
intermediates := x509.NewCertPool()
for _, v := range x5c[1:] {
der, ok = v.([]byte)
if !ok {
return nil, NewError(ErrorBadAttestationStatementType, "x5c is malformed")
return nil, NewDetailedError(ErrorBadAttestationStatementType, "x5c is malformed")
}
cert, err := x509.ParseCertificate(der)
if err != nil {
return nil, WrapError(ErrorBadAttestationStatementType, err, "x5c is malformed")
return nil, WrapDetailedError(ErrorBadAttestationStatementType, err, "x5c is malformed")
}
intermediates.AddCert(cert)
}
@ -591,7 +987,7 @@ func doStepAttestationFormat(ctx context.Context, prov Provisioner, ch *Challeng
CurrentTime: time.Now().Truncate(time.Second),
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
}); err != nil {
return nil, WrapError(ErrorBadAttestationStatementType, err, "x5c is not valid")
return nil, WrapDetailedError(ErrorBadAttestationStatementType, err, "x5c is not valid")
}
// Verify proof of possession of private key validating the key
@ -601,10 +997,10 @@ func doStepAttestationFormat(ctx context.Context, prov Provisioner, ch *Challeng
var sig []byte
csig, ok := att.AttStatement["sig"].([]byte)
if !ok {
return nil, NewError(ErrorBadAttestationStatementType, "sig not present")
return nil, NewDetailedError(ErrorBadAttestationStatementType, "sig not present")
}
if err := cbor.Unmarshal(csig, &sig); err != nil {
return nil, NewError(ErrorBadAttestationStatementType, "sig is malformed")
return nil, NewDetailedError(ErrorBadAttestationStatementType, "sig is malformed")
}
keyAuth, err := KeyAuthorization(ch.Token, jwk)
if err != nil {
@ -614,23 +1010,23 @@ func doStepAttestationFormat(ctx context.Context, prov Provisioner, ch *Challeng
switch pub := leaf.PublicKey.(type) {
case *ecdsa.PublicKey:
if pub.Curve != elliptic.P256() {
return nil, WrapError(ErrorBadAttestationStatementType, err, "unsupported elliptic curve %s", pub.Curve)
return nil, WrapDetailedError(ErrorBadAttestationStatementType, err, "unsupported elliptic curve %s", pub.Curve)
}
sum := sha256.Sum256([]byte(keyAuth))
if !ecdsa.VerifyASN1(pub, sum[:], sig) {
return nil, NewError(ErrorBadAttestationStatementType, "failed to validate signature")
return nil, NewDetailedError(ErrorBadAttestationStatementType, "failed to validate signature")
}
case *rsa.PublicKey:
sum := sha256.Sum256([]byte(keyAuth))
if err := rsa.VerifyPKCS1v15(pub, crypto.SHA256, sum[:], sig); err != nil {
return nil, NewError(ErrorBadAttestationStatementType, "failed to validate signature")
return nil, NewDetailedError(ErrorBadAttestationStatementType, "failed to validate signature")
}
case ed25519.PublicKey:
if !ed25519.Verify(pub, []byte(keyAuth), sig) {
return nil, NewError(ErrorBadAttestationStatementType, "failed to validate signature")
return nil, NewDetailedError(ErrorBadAttestationStatementType, "failed to validate signature")
}
default:
return nil, NewError(ErrorBadAttestationStatementType, "unsupported public key type %T", pub)
return nil, NewDetailedError(ErrorBadAttestationStatementType, "unsupported public key type %T", pub)
}
// Parse attestation data:
@ -638,6 +1034,9 @@ func doStepAttestationFormat(ctx context.Context, prov Provisioner, ch *Challeng
data := &stepAttestationData{
Certificate: leaf,
}
if data.Fingerprint, err = keyutil.Fingerprint(leaf.PublicKey); err != nil {
return nil, WrapErrorISE(err, "error calculating key fingerprint")
}
for _, ext := range leaf.Extensions {
if !ext.Id.Equal(oidYubicoSerialNumber) {
continue
@ -701,10 +1100,10 @@ func uitoa(val uint) string {
var buf [20]byte // big enough for 64bit value base 10
i := len(buf) - 1
for val >= 10 {
q := val / 10
buf[i] = byte('0' + val - q*10)
v := val / 10
buf[i] = byte('0' + val - v*10)
i--
val = q
val = v
}
// val < 10
buf[i] = byte('0' + val)

File diff suppressed because it is too large Load Diff

@ -0,0 +1,860 @@
//go:build tpmsimulator
// +build tpmsimulator
package acme
import (
"context"
"crypto"
"crypto/sha256"
"crypto/x509"
"encoding/asn1"
"encoding/base64"
"encoding/json"
"encoding/pem"
"errors"
"fmt"
"net/url"
"testing"
"github.com/fxamacker/cbor/v2"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/smallstep/go-attestation/attest"
"go.step.sm/crypto/jose"
"go.step.sm/crypto/keyutil"
"go.step.sm/crypto/minica"
"go.step.sm/crypto/tpm"
"go.step.sm/crypto/tpm/simulator"
tpmstorage "go.step.sm/crypto/tpm/storage"
"go.step.sm/crypto/x509util"
)
func newSimulatedTPM(t *testing.T) *tpm.TPM {
t.Helper()
tmpDir := t.TempDir()
tpm, err := tpm.New(withSimulator(t), tpm.WithStore(tpmstorage.NewDirstore(tmpDir))) // TODO: provide in-memory storage implementation instead
require.NoError(t, err)
return tpm
}
func withSimulator(t *testing.T) tpm.NewTPMOption {
t.Helper()
var sim simulator.Simulator
t.Cleanup(func() {
if sim == nil {
return
}
err := sim.Close()
require.NoError(t, err)
})
sim, err := simulator.New()
require.NoError(t, err)
err = sim.Open()
require.NoError(t, err)
return tpm.WithSimulator(sim)
}
func generateKeyID(t *testing.T, pub crypto.PublicKey) []byte {
t.Helper()
b, err := x509.MarshalPKIXPublicKey(pub)
require.NoError(t, err)
hash := sha256.Sum256(b)
return hash[:]
}
func mustAttestTPM(t *testing.T, keyAuthorization string, permanentIdentifiers []string) ([]byte, crypto.Signer, *x509.Certificate) {
t.Helper()
aca, err := minica.New(
minica.WithName("TPM Testing"),
minica.WithGetSignerFunc(
func() (crypto.Signer, error) {
return keyutil.GenerateSigner("RSA", "", 2048)
},
),
)
require.NoError(t, err)
// prepare simulated TPM and create an AK
stpm := newSimulatedTPM(t)
eks, err := stpm.GetEKs(context.Background())
require.NoError(t, err)
ak, err := stpm.CreateAK(context.Background(), "first-ak")
require.NoError(t, err)
require.NotNil(t, ak)
// extract the AK public key // TODO(hs): replace this when there's a simpler method to get the AK public key (e.g. ak.Public())
ap, err := ak.AttestationParameters(context.Background())
require.NoError(t, err)
akp, err := attest.ParseAKPublic(attest.TPMVersion20, ap.Public)
require.NoError(t, err)
// create template and sign certificate for the AK public key
keyID := generateKeyID(t, eks[0].Public())
template := &x509.Certificate{
PublicKey: akp.Public,
IsCA: false,
UnknownExtKeyUsage: []asn1.ObjectIdentifier{oidTCGKpAIKCertificate},
}
sans := []x509util.SubjectAlternativeName{}
uris := []*url.URL{{Scheme: "urn", Opaque: "ek:sha256:" + base64.StdEncoding.EncodeToString(keyID)}}
for _, pi := range permanentIdentifiers {
sans = append(sans, x509util.SubjectAlternativeName{
Type: x509util.PermanentIdentifierType,
Value: pi,
})
}
asn1Value := []byte(fmt.Sprintf(`{"extraNames":[{"type": %q, "value": %q},{"type": %q, "value": %q},{"type": %q, "value": %q}]}`, oidTPMManufacturer, "1414747215", oidTPMModel, "SLB 9670 TPM2.0", oidTPMVersion, "7.55"))
sans = append(sans, x509util.SubjectAlternativeName{
Type: x509util.DirectoryNameType,
ASN1Value: asn1Value,
})
ext, err := createSubjectAltNameExtension(nil, nil, nil, uris, sans, true)
require.NoError(t, err)
ext.Set(template)
akCert, err := aca.Sign(template)
require.NoError(t, err)
require.NotNil(t, akCert)
// create a new key attested by the AK, while including
// the key authorization bytes as qualifying data.
keyAuthSum := sha256.Sum256([]byte(keyAuthorization))
config := tpm.AttestKeyConfig{
Algorithm: "RSA",
Size: 2048,
QualifyingData: keyAuthSum[:],
}
key, err := stpm.AttestKey(context.Background(), "first-ak", "first-key", config)
require.NoError(t, err)
require.NotNil(t, key)
require.Equal(t, "first-key", key.Name())
require.NotEqual(t, 0, len(key.Data()))
require.Equal(t, "first-ak", key.AttestedBy())
require.True(t, key.WasAttested())
require.True(t, key.WasAttestedBy(ak))
signer, err := key.Signer(context.Background())
require.NoError(t, err)
// prepare the attestation object with the AK certificate chain,
// the attested key, its metadata and the signature signed by the
// AK.
params, err := key.CertificationParameters(context.Background())
require.NoError(t, err)
attObj, err := cbor.Marshal(struct {
Format string `json:"fmt"`
AttStatement map[string]interface{} `json:"attStmt,omitempty"`
}{
Format: "tpm",
AttStatement: map[string]interface{}{
"ver": "2.0",
"x5c": []interface{}{akCert.Raw, aca.Intermediate.Raw},
"alg": int64(-257), // RS256
"sig": params.CreateSignature,
"certInfo": params.CreateAttestation,
"pubArea": params.Public,
},
})
require.NoError(t, err)
// marshal the ACME payload
payload, err := json.Marshal(struct {
AttObj string `json:"attObj"`
}{
AttObj: base64.RawURLEncoding.EncodeToString(attObj),
})
require.NoError(t, err)
return payload, signer, aca.Root
}
func Test_deviceAttest01ValidateWithTPMSimulator(t *testing.T) {
type args struct {
ctx context.Context
ch *Challenge
db DB
jwk *jose.JSONWebKey
payload []byte
}
type test struct {
args args
wantErr *Error
}
tests := map[string]func(t *testing.T) test{
"ok/doTPMAttestationFormat-storeError": func(t *testing.T) test {
jwk, keyAuth := mustAccountAndKeyAuthorization(t, "token")
payload, _, root := mustAttestTPM(t, keyAuth, nil) // TODO: value(s) for AK cert?
caRoot := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: root.Raw})
ctx := NewProvisionerContext(context.Background(), mustAttestationProvisioner(t, caRoot))
// parse payload, set invalid "ver", remarshal
var p payloadType
err := json.Unmarshal(payload, &p)
require.NoError(t, err)
attObj, err := base64.RawURLEncoding.DecodeString(p.AttObj)
require.NoError(t, err)
att := attestationObject{}
err = cbor.Unmarshal(attObj, &att)
require.NoError(t, err)
att.AttStatement["ver"] = "bogus"
attObj, err = cbor.Marshal(struct {
Format string `json:"fmt"`
AttStatement map[string]interface{} `json:"attStmt,omitempty"`
}{
Format: "tpm",
AttStatement: att.AttStatement,
})
require.NoError(t, err)
payload, err = json.Marshal(struct {
AttObj string `json:"attObj"`
}{
AttObj: base64.RawURLEncoding.EncodeToString(attObj),
})
require.NoError(t, err)
return test{
args: args{
ctx: ctx,
jwk: jwk,
ch: &Challenge{
ID: "chID",
AuthorizationID: "azID",
Token: "token",
Type: "device-attest-01",
Status: StatusPending,
Value: "device.id.12345678",
},
payload: payload,
db: &MockDB{
MockGetAuthorization: func(ctx context.Context, id string) (*Authorization, error) {
assert.Equal(t, "azID", id)
return &Authorization{ID: "azID"}, nil
},
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
assert.Equal(t, "chID", updch.ID)
assert.Equal(t, "token", updch.Token)
assert.Equal(t, StatusInvalid, updch.Status)
assert.Equal(t, ChallengeType("device-attest-01"), updch.Type)
assert.Equal(t, "device.id.12345678", updch.Value)
err := NewDetailedError(ErrorBadAttestationStatementType, `version "bogus" is not supported`)
assert.EqualError(t, updch.Error.Err, err.Err.Error())
assert.Equal(t, err.Type, updch.Error.Type)
assert.Equal(t, err.Detail, updch.Error.Detail)
assert.Equal(t, err.Status, updch.Error.Status)
assert.Equal(t, err.Subproblems, updch.Error.Subproblems)
return nil
},
},
},
wantErr: nil,
}
},
"ok with invalid PermanentIdentifier SAN": func(t *testing.T) test {
jwk, keyAuth := mustAccountAndKeyAuthorization(t, "token")
payload, _, root := mustAttestTPM(t, keyAuth, []string{"device.id.12345678"}) // TODO: value(s) for AK cert?
caRoot := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: root.Raw})
ctx := NewProvisionerContext(context.Background(), mustAttestationProvisioner(t, caRoot))
return test{
args: args{
ctx: ctx,
jwk: jwk,
ch: &Challenge{
ID: "chID",
AuthorizationID: "azID",
Token: "token",
Type: "device-attest-01",
Status: StatusPending,
Value: "device.id.99999999",
},
payload: payload,
db: &MockDB{
MockGetAuthorization: func(ctx context.Context, id string) (*Authorization, error) {
assert.Equal(t, "azID", id)
return &Authorization{ID: "azID"}, nil
},
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
assert.Equal(t, "chID", updch.ID)
assert.Equal(t, "token", updch.Token)
assert.Equal(t, StatusInvalid, updch.Status)
assert.Equal(t, ChallengeType("device-attest-01"), updch.Type)
assert.Equal(t, "device.id.99999999", updch.Value)
err := NewDetailedError(ErrorBadAttestationStatementType, `permanent identifier does not match`).
AddSubproblems(NewSubproblemWithIdentifier(
ErrorRejectedIdentifierType,
Identifier{Type: "permanent-identifier", Value: "device.id.99999999"},
`challenge identifier "device.id.99999999" doesn't match any of the attested hardware identifiers ["device.id.12345678"]`,
))
assert.EqualError(t, updch.Error.Err, err.Err.Error())
assert.Equal(t, err.Type, updch.Error.Type)
assert.Equal(t, err.Detail, updch.Error.Detail)
assert.Equal(t, err.Status, updch.Error.Status)
assert.Equal(t, err.Subproblems, updch.Error.Subproblems)
return nil
},
},
},
wantErr: nil,
}
},
"ok": func(t *testing.T) test {
jwk, keyAuth := mustAccountAndKeyAuthorization(t, "token")
payload, signer, root := mustAttestTPM(t, keyAuth, nil) // TODO: value(s) for AK cert?
caRoot := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: root.Raw})
ctx := NewProvisionerContext(context.Background(), mustAttestationProvisioner(t, caRoot))
return test{
args: args{
ctx: ctx,
jwk: jwk,
ch: &Challenge{
ID: "chID",
AuthorizationID: "azID",
Token: "token",
Type: "device-attest-01",
Status: StatusPending,
Value: "device.id.12345678",
},
payload: payload,
db: &MockDB{
MockGetAuthorization: func(ctx context.Context, id string) (*Authorization, error) {
assert.Equal(t, "azID", id)
return &Authorization{ID: "azID"}, nil
},
MockUpdateAuthorization: func(ctx context.Context, az *Authorization) error {
fingerprint, err := keyutil.Fingerprint(signer.Public())
assert.NoError(t, err)
assert.Equal(t, "azID", az.ID)
assert.Equal(t, fingerprint, az.Fingerprint)
return nil
},
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
assert.Equal(t, "chID", updch.ID)
assert.Equal(t, "token", updch.Token)
assert.Equal(t, StatusValid, updch.Status)
assert.Equal(t, ChallengeType("device-attest-01"), updch.Type)
assert.Equal(t, "device.id.12345678", updch.Value)
return nil
},
},
},
wantErr: nil,
}
},
"ok with PermanentIdentifier SAN": func(t *testing.T) test {
jwk, keyAuth := mustAccountAndKeyAuthorization(t, "token")
payload, signer, root := mustAttestTPM(t, keyAuth, []string{"device.id.12345678"}) // TODO: value(s) for AK cert?
caRoot := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: root.Raw})
ctx := NewProvisionerContext(context.Background(), mustAttestationProvisioner(t, caRoot))
return test{
args: args{
ctx: ctx,
jwk: jwk,
ch: &Challenge{
ID: "chID",
AuthorizationID: "azID",
Token: "token",
Type: "device-attest-01",
Status: StatusPending,
Value: "device.id.12345678",
},
payload: payload,
db: &MockDB{
MockGetAuthorization: func(ctx context.Context, id string) (*Authorization, error) {
assert.Equal(t, "azID", id)
return &Authorization{ID: "azID"}, nil
},
MockUpdateAuthorization: func(ctx context.Context, az *Authorization) error {
fingerprint, err := keyutil.Fingerprint(signer.Public())
assert.NoError(t, err)
assert.Equal(t, "azID", az.ID)
assert.Equal(t, fingerprint, az.Fingerprint)
return nil
},
MockUpdateChallenge: func(ctx context.Context, updch *Challenge) error {
assert.Equal(t, "chID", updch.ID)
assert.Equal(t, "token", updch.Token)
assert.Equal(t, StatusValid, updch.Status)
assert.Equal(t, ChallengeType("device-attest-01"), updch.Type)
assert.Equal(t, "device.id.12345678", updch.Value)
return nil
},
},
},
wantErr: nil,
}
},
}
for name, run := range tests {
t.Run(name, func(t *testing.T) {
tc := run(t)
if err := deviceAttest01Validate(tc.args.ctx, tc.args.ch, tc.args.db, tc.args.jwk, tc.args.payload); err != nil {
assert.Error(t, tc.wantErr)
assert.EqualError(t, err, tc.wantErr.Error())
return
}
assert.Nil(t, tc.wantErr)
})
}
}
func newBadAttestationStatementError(msg string) *Error {
return &Error{
Type: "urn:ietf:params:acme:error:badAttestationStatement",
Status: 400,
Err: errors.New(msg),
}
}
func newInternalServerError(msg string) *Error {
return &Error{
Type: "urn:ietf:params:acme:error:serverInternal",
Status: 500,
Err: errors.New(msg),
}
}
var (
oidPermanentIdentifier = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 8, 3}
oidHardwareModuleNameIdentifier = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 8, 4}
)
func Test_doTPMAttestationFormat(t *testing.T) {
ctx := context.Background()
aca, err := minica.New(
minica.WithName("TPM Testing"),
minica.WithGetSignerFunc(
func() (crypto.Signer, error) {
return keyutil.GenerateSigner("RSA", "", 2048)
},
),
)
require.NoError(t, err)
acaRoot := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: aca.Root.Raw})
// prepare simulated TPM and create an AK
stpm := newSimulatedTPM(t)
eks, err := stpm.GetEKs(context.Background())
require.NoError(t, err)
ak, err := stpm.CreateAK(context.Background(), "first-ak")
require.NoError(t, err)
require.NotNil(t, ak)
// extract the AK public key // TODO(hs): replace this when there's a simpler method to get the AK public key (e.g. ak.Public())
ap, err := ak.AttestationParameters(context.Background())
require.NoError(t, err)
akp, err := attest.ParseAKPublic(attest.TPMVersion20, ap.Public)
require.NoError(t, err)
// create template and sign certificate for the AK public key
keyID := generateKeyID(t, eks[0].Public())
template := &x509.Certificate{
PublicKey: akp.Public,
IsCA: false,
UnknownExtKeyUsage: []asn1.ObjectIdentifier{oidTCGKpAIKCertificate},
}
sans := []x509util.SubjectAlternativeName{}
uris := []*url.URL{{Scheme: "urn", Opaque: "ek:sha256:" + base64.StdEncoding.EncodeToString(keyID)}}
asn1Value := []byte(fmt.Sprintf(`{"extraNames":[{"type": %q, "value": %q},{"type": %q, "value": %q},{"type": %q, "value": %q}]}`, oidTPMManufacturer, "1414747215", oidTPMModel, "SLB 9670 TPM2.0", oidTPMVersion, "7.55"))
sans = append(sans, x509util.SubjectAlternativeName{
Type: x509util.DirectoryNameType,
ASN1Value: asn1Value,
})
ext, err := createSubjectAltNameExtension(nil, nil, nil, uris, sans, true)
require.NoError(t, err)
ext.Set(template)
akCert, err := aca.Sign(template)
require.NoError(t, err)
require.NotNil(t, akCert)
invalidTemplate := &x509.Certificate{
PublicKey: akp.Public,
IsCA: false,
UnknownExtKeyUsage: []asn1.ObjectIdentifier{oidTCGKpAIKCertificate},
}
invalidAKCert, err := aca.Sign(invalidTemplate)
require.NoError(t, err)
require.NotNil(t, invalidAKCert)
// generate a JWK and the key authorization value
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
require.NoError(t, err)
keyAuthorization, err := KeyAuthorization("token", jwk)
require.NoError(t, err)
// create a new key attested by the AK, while including
// the key authorization bytes as qualifying data.
keyAuthSum := sha256.Sum256([]byte(keyAuthorization))
config := tpm.AttestKeyConfig{
Algorithm: "RSA",
Size: 2048,
QualifyingData: keyAuthSum[:],
}
key, err := stpm.AttestKey(context.Background(), "first-ak", "first-key", config)
require.NoError(t, err)
require.NotNil(t, key)
params, err := key.CertificationParameters(context.Background())
require.NoError(t, err)
signer, err := key.Signer(context.Background())
require.NoError(t, err)
fingerprint, err := keyutil.Fingerprint(signer.Public())
require.NoError(t, err)
// attest another key and get its certification parameters
anotherKey, err := stpm.AttestKey(context.Background(), "first-ak", "another-key", config)
require.NoError(t, err)
require.NotNil(t, key)
anotherKeyParams, err := anotherKey.CertificationParameters(context.Background())
require.NoError(t, err)
type args struct {
ctx context.Context
prov Provisioner
ch *Challenge
jwk *jose.JSONWebKey
att *attestationObject
}
tests := []struct {
name string
args args
want *tpmAttestationData
expErr *Error
}{
{"ok", args{ctx, mustAttestationProvisioner(t, acaRoot), &Challenge{Token: "token"}, jwk, &attestationObject{
Format: "tpm",
AttStatement: map[string]interface{}{
"ver": "2.0",
"x5c": []interface{}{akCert.Raw, aca.Intermediate.Raw},
"alg": int64(-257), // RS256
"sig": params.CreateSignature,
"certInfo": params.CreateAttestation,
"pubArea": params.Public,
},
}}, nil, nil},
{"fail ver not present", args{ctx, mustAttestationProvisioner(t, acaRoot), &Challenge{Token: "token"}, jwk, &attestationObject{
Format: "tpm",
AttStatement: map[string]interface{}{
"x5c": []interface{}{akCert.Raw, aca.Intermediate.Raw},
"alg": int64(-257), // RS256
"sig": params.CreateSignature,
"certInfo": params.CreateAttestation,
"pubArea": params.Public,
},
}}, nil, newBadAttestationStatementError("ver not present")},
{"fail ver type", args{ctx, mustAttestationProvisioner(t, acaRoot), &Challenge{Token: "token"}, jwk, &attestationObject{
Format: "tpm",
AttStatement: map[string]interface{}{
"ver": []interface{}{},
"x5c": []interface{}{akCert.Raw, aca.Intermediate.Raw},
"alg": int64(-257), // RS256
"sig": params.CreateSignature,
"certInfo": params.CreateAttestation,
"pubArea": params.Public,
},
}}, nil, newBadAttestationStatementError("ver not present")},
{"fail bogus ver", args{ctx, mustAttestationProvisioner(t, acaRoot), &Challenge{Token: "token"}, jwk, &attestationObject{
Format: "tpm",
AttStatement: map[string]interface{}{
"ver": "bogus",
"x5c": []interface{}{akCert.Raw, aca.Intermediate.Raw},
"alg": int64(-257), // RS256
"sig": params.CreateSignature,
"certInfo": params.CreateAttestation,
"pubArea": params.Public,
},
}}, nil, newBadAttestationStatementError(`version "bogus" is not supported`)},
{"fail x5c not present", args{ctx, mustAttestationProvisioner(t, acaRoot), &Challenge{Token: "token"}, jwk, &attestationObject{
Format: "tpm",
AttStatement: map[string]interface{}{
"ver": "2.0",
"alg": int64(-257), // RS256
"sig": params.CreateSignature,
"certInfo": params.CreateAttestation,
"pubArea": params.Public,
},
}}, nil, newBadAttestationStatementError("x5c not present")},
{"fail x5c type", args{ctx, mustAttestationProvisioner(t, acaRoot), &Challenge{Token: "token"}, jwk, &attestationObject{
Format: "tpm",
AttStatement: map[string]interface{}{
"ver": "2.0",
"x5c": [][]byte{akCert.Raw, aca.Intermediate.Raw},
"alg": int64(-257), // RS256
"sig": params.CreateSignature,
"certInfo": params.CreateAttestation,
"pubArea": params.Public,
},
}}, nil, newBadAttestationStatementError("x5c not present")},
{"fail x5c empty", args{ctx, mustAttestationProvisioner(t, acaRoot), &Challenge{Token: "token"}, jwk, &attestationObject{
Format: "tpm",
AttStatement: map[string]interface{}{
"ver": "2.0",
"x5c": []interface{}{},
"alg": int64(-257), // RS256
"sig": params.CreateSignature,
"certInfo": params.CreateAttestation,
"pubArea": params.Public,
},
}}, nil, newBadAttestationStatementError("x5c is empty")},
{"fail leaf type", args{ctx, mustAttestationProvisioner(t, acaRoot), &Challenge{Token: "token"}, jwk, &attestationObject{
Format: "step",
AttStatement: map[string]interface{}{
"ver": "2.0",
"x5c": []interface{}{"leaf", aca.Intermediate.Raw},
"alg": int64(-257), // RS256
"sig": params.CreateSignature,
"certInfo": params.CreateAttestation,
"pubArea": params.Public,
},
}}, nil, newBadAttestationStatementError("x5c is malformed")},
{"fail leaf parse", args{ctx, mustAttestationProvisioner(t, acaRoot), &Challenge{Token: "token"}, jwk, &attestationObject{
Format: "step",
AttStatement: map[string]interface{}{
"ver": "2.0",
"x5c": []interface{}{akCert.Raw[:100], aca.Intermediate.Raw},
"alg": int64(-257), // RS256
"sig": params.CreateSignature,
"certInfo": params.CreateAttestation,
"pubArea": params.Public,
},
}}, nil, newBadAttestationStatementError("x5c is malformed: x509: malformed certificate")},
{"fail intermediate type", args{ctx, mustAttestationProvisioner(t, acaRoot), &Challenge{Token: "token"}, jwk, &attestationObject{
Format: "step",
AttStatement: map[string]interface{}{
"ver": "2.0",
"x5c": []interface{}{akCert.Raw, "intermediate"},
"alg": int64(-257), // RS256
"sig": params.CreateSignature,
"certInfo": params.CreateAttestation,
"pubArea": params.Public,
},
}}, nil, newBadAttestationStatementError("x5c is malformed")},
{"fail intermediate parse", args{ctx, mustAttestationProvisioner(t, acaRoot), &Challenge{Token: "token"}, jwk, &attestationObject{
Format: "step",
AttStatement: map[string]interface{}{
"ver": "2.0",
"x5c": []interface{}{akCert.Raw, aca.Intermediate.Raw[:100]},
"alg": int64(-257), // RS256
"sig": params.CreateSignature,
"certInfo": params.CreateAttestation,
"pubArea": params.Public,
},
}}, nil, newBadAttestationStatementError("x5c is malformed: x509: malformed certificate")},
{"fail roots", args{ctx, mustAttestationProvisioner(t, nil), &Challenge{Token: "token"}, jwk, &attestationObject{
Format: "tpm",
AttStatement: map[string]interface{}{
"ver": "2.0",
"x5c": []interface{}{akCert.Raw, aca.Intermediate.Raw},
"alg": int64(-257), // RS256
"sig": params.CreateSignature,
"certInfo": params.CreateAttestation,
"pubArea": params.Public,
},
}}, nil, newInternalServerError("no root CA bundle available to verify the attestation certificate")},
{"fail verify", args{ctx, mustAttestationProvisioner(t, acaRoot), &Challenge{Token: "token"}, jwk, &attestationObject{
Format: "step",
AttStatement: map[string]interface{}{
"ver": "2.0",
"x5c": []interface{}{akCert.Raw},
"alg": int64(-257), // RS256
"sig": params.CreateSignature,
"certInfo": params.CreateAttestation,
"pubArea": params.Public,
},
}}, nil, newBadAttestationStatementError("x5c is not valid: x509: certificate signed by unknown authority")},
{"fail validateAKCertificate", args{ctx, mustAttestationProvisioner(t, acaRoot), &Challenge{Token: "token"}, jwk, &attestationObject{
Format: "tpm",
AttStatement: map[string]interface{}{
"ver": "2.0",
"x5c": []interface{}{invalidAKCert.Raw, aca.Intermediate.Raw},
"alg": int64(-257), // RS256
"sig": params.CreateSignature,
"certInfo": params.CreateAttestation,
"pubArea": params.Public,
},
}}, nil, newBadAttestationStatementError("AK certificate is not valid: missing TPM manufacturer")},
{"fail pubArea not present", args{ctx, mustAttestationProvisioner(t, acaRoot), &Challenge{Token: "token"}, jwk, &attestationObject{
Format: "tpm",
AttStatement: map[string]interface{}{
"ver": "2.0",
"x5c": []interface{}{akCert.Raw, aca.Intermediate.Raw},
"alg": int64(-257), // RS256
"sig": params.CreateSignature,
"certInfo": params.CreateAttestation,
},
}}, nil, newBadAttestationStatementError("invalid pubArea in attestation statement")},
{"fail pubArea type", args{ctx, mustAttestationProvisioner(t, acaRoot), &Challenge{Token: "token"}, jwk, &attestationObject{
Format: "tpm",
AttStatement: map[string]interface{}{
"ver": "2.0",
"x5c": []interface{}{akCert.Raw, aca.Intermediate.Raw},
"alg": int64(-257), // RS256
"sig": params.CreateSignature,
"certInfo": params.CreateAttestation,
"pubArea": []interface{}{},
},
}}, nil, newBadAttestationStatementError("invalid pubArea in attestation statement")},
{"fail pubArea empty", args{ctx, mustAttestationProvisioner(t, acaRoot), &Challenge{Token: "token"}, jwk, &attestationObject{
Format: "tpm",
AttStatement: map[string]interface{}{
"ver": "2.0",
"x5c": []interface{}{akCert.Raw, aca.Intermediate.Raw},
"alg": int64(-257), // RS256
"sig": params.CreateSignature,
"certInfo": params.CreateAttestation,
"pubArea": []byte{},
},
}}, nil, newBadAttestationStatementError("pubArea is empty")},
{"fail sig not present", args{ctx, mustAttestationProvisioner(t, acaRoot), &Challenge{Token: "token"}, jwk, &attestationObject{
Format: "tpm",
AttStatement: map[string]interface{}{
"ver": "2.0",
"x5c": []interface{}{akCert.Raw, aca.Intermediate.Raw},
"alg": int64(-257), // RS256
"certInfo": params.CreateAttestation,
"pubArea": params.Public,
},
}}, nil, newBadAttestationStatementError("invalid sig in attestation statement")},
{"fail sig type", args{ctx, mustAttestationProvisioner(t, acaRoot), &Challenge{Token: "token"}, jwk, &attestationObject{
Format: "tpm",
AttStatement: map[string]interface{}{
"ver": "2.0",
"x5c": []interface{}{akCert.Raw, aca.Intermediate.Raw},
"alg": int64(-257), // RS256
"sig": []interface{}{},
"certInfo": params.CreateAttestation,
"pubArea": params.Public,
},
}}, nil, newBadAttestationStatementError("invalid sig in attestation statement")},
{"fail sig empty", args{ctx, mustAttestationProvisioner(t, acaRoot), &Challenge{Token: "token"}, jwk, &attestationObject{
Format: "tpm",
AttStatement: map[string]interface{}{
"ver": "2.0",
"x5c": []interface{}{akCert.Raw, aca.Intermediate.Raw},
"alg": int64(-257), // RS256
"sig": []byte{},
"certInfo": params.CreateAttestation,
"pubArea": params.Public,
},
}}, nil, newBadAttestationStatementError("sig is empty")},
{"fail certInfo not present", args{ctx, mustAttestationProvisioner(t, acaRoot), &Challenge{Token: "token"}, jwk, &attestationObject{
Format: "tpm",
AttStatement: map[string]interface{}{
"ver": "2.0",
"x5c": []interface{}{akCert.Raw, aca.Intermediate.Raw},
"alg": int64(-257), // RS256
"sig": params.CreateSignature,
"pubArea": params.Public,
},
}}, nil, newBadAttestationStatementError("invalid certInfo in attestation statement")},
{"fail certInfo type", args{ctx, mustAttestationProvisioner(t, acaRoot), &Challenge{Token: "token"}, jwk, &attestationObject{
Format: "tpm",
AttStatement: map[string]interface{}{
"ver": "2.0",
"x5c": []interface{}{akCert.Raw, aca.Intermediate.Raw},
"alg": int64(-257), // RS256
"sig": params.CreateSignature,
"certInfo": []interface{}{},
"pubArea": params.Public,
},
}}, nil, newBadAttestationStatementError("invalid certInfo in attestation statement")},
{"fail certInfo empty", args{ctx, mustAttestationProvisioner(t, acaRoot), &Challenge{Token: "token"}, jwk, &attestationObject{
Format: "tpm",
AttStatement: map[string]interface{}{
"ver": "2.0",
"x5c": []interface{}{akCert.Raw, aca.Intermediate.Raw},
"alg": int64(-257), // RS256
"sig": params.CreateSignature,
"certInfo": []byte{},
"pubArea": params.Public,
},
}}, nil, newBadAttestationStatementError("certInfo is empty")},
{"fail alg not present", args{ctx, mustAttestationProvisioner(t, acaRoot), &Challenge{Token: "token"}, jwk, &attestationObject{
Format: "tpm",
AttStatement: map[string]interface{}{
"ver": "2.0",
"x5c": []interface{}{akCert.Raw, aca.Intermediate.Raw},
"sig": params.CreateSignature,
"certInfo": params.CreateAttestation,
"pubArea": params.Public,
},
}}, nil, newBadAttestationStatementError("invalid alg in attestation statement")},
{"fail alg type", args{ctx, mustAttestationProvisioner(t, acaRoot), &Challenge{Token: "token"}, jwk, &attestationObject{
Format: "tpm",
AttStatement: map[string]interface{}{
"ver": "2.0",
"x5c": []interface{}{akCert.Raw, aca.Intermediate.Raw},
"alg": int64(0), // invalid alg
"sig": params.CreateSignature,
"certInfo": params.CreateAttestation,
"pubArea": params.Public,
},
}}, nil, newBadAttestationStatementError("invalid alg 0 in attestation statement")},
{"fail attestation verification", args{ctx, mustAttestationProvisioner(t, acaRoot), &Challenge{Token: "token"}, jwk, &attestationObject{
Format: "tpm",
AttStatement: map[string]interface{}{
"ver": "2.0",
"x5c": []interface{}{akCert.Raw, aca.Intermediate.Raw},
"alg": int64(-257), // RS256
"sig": params.CreateSignature,
"certInfo": params.CreateAttestation,
"pubArea": anotherKeyParams.Public,
},
}}, nil, newBadAttestationStatementError("invalid certification parameters: certification refers to a different key")},
{"fail keyAuthorization", args{ctx, mustAttestationProvisioner(t, acaRoot), &Challenge{Token: "token"}, &jose.JSONWebKey{Key: []byte("not an asymmetric key")}, &attestationObject{
Format: "tpm",
AttStatement: map[string]interface{}{
"ver": "2.0",
"x5c": []interface{}{akCert.Raw, aca.Intermediate.Raw},
"alg": int64(-257), // RS256
"sig": params.CreateSignature,
"certInfo": params.CreateAttestation,
"pubArea": params.Public,
},
}}, nil, newInternalServerError("failed creating key auth digest: error generating JWK thumbprint: go-jose/go-jose: unknown key type '[]uint8'")},
{"fail different keyAuthorization", args{ctx, mustAttestationProvisioner(t, acaRoot), &Challenge{Token: "aDifferentToken"}, jwk, &attestationObject{
Format: "tpm",
AttStatement: map[string]interface{}{
"ver": "2.0",
"x5c": []interface{}{akCert.Raw, aca.Intermediate.Raw},
"alg": int64(-257), //
"sig": params.CreateSignature,
"certInfo": params.CreateAttestation,
"pubArea": params.Public,
},
}}, nil, newBadAttestationStatementError("key authorization invalid")},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := doTPMAttestationFormat(tt.args.ctx, tt.args.prov, tt.args.ch, tt.args.jwk, tt.args.att)
if tt.expErr != nil {
var ae *Error
if assert.True(t, errors.As(err, &ae)) {
assert.EqualError(t, err, tt.expErr.Error())
assert.Equal(t, ae.StatusCode(), tt.expErr.StatusCode())
assert.Equal(t, ae.Type, tt.expErr.Type)
}
assert.Nil(t, got)
return
}
assert.NoError(t, err)
if assert.NotNil(t, got) {
assert.Equal(t, akCert, got.Certificate)
assert.Equal(t, [][]*x509.Certificate{
{
akCert, aca.Intermediate, aca.Root,
},
}, got.VerifiedChains)
assert.Equal(t, fingerprint, got.Fingerprint)
assert.Empty(t, got.PermanentIdentifiers) // currently expected to be always empty
}
})
}
}

@ -55,6 +55,7 @@ func NewClient() Client {
http: &http.Client{
Timeout: 30 * time.Second,
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
TLSClientConfig: &tls.Config{
//nolint:gosec // used on tls-alpn-01 challenge
InsecureSkipVerify: true, // lgtm[go/disabled-certificate-check]

@ -21,7 +21,7 @@ var clock Clock
// CertificateAuthority is the interface implemented by a CA authority.
type CertificateAuthority interface {
Sign(cr *x509.CertificateRequest, opts provisioner.SignOptions, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error)
SignWithContext(ctx context.Context, cr *x509.CertificateRequest, opts provisioner.SignOptions, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error)
AreSANsAllowed(ctx context.Context, sans []string) error
IsRevoked(sn string) (bool, error)
Revoke(context.Context, *authority.RevokeOptions) error
@ -46,7 +46,7 @@ type PrerequisitesChecker func(ctx context.Context) (bool, error)
// DefaultPrerequisitesChecker is the default PrerequisiteChecker and returns
// always true.
func DefaultPrerequisitesChecker(ctx context.Context) (bool, error) {
func DefaultPrerequisitesChecker(context.Context) (bool, error) {
return true, nil
}
@ -93,14 +93,17 @@ func ProvisionerFromContext(ctx context.Context) (v Provisioner, ok bool) {
return
}
// MustLinkerFromContext returns the current provisioner from the given context.
// MustProvisionerFromContext returns the current provisioner from the given context.
// It will panic if it's not in the context.
func MustProvisionerFromContext(ctx context.Context) Provisioner {
if v, ok := ProvisionerFromContext(ctx); !ok {
var (
v Provisioner
ok bool
)
if v, ok = ProvisionerFromContext(ctx); !ok {
panic("acme provisioner is not the context")
} else {
return v
}
return v
}
// MockProvisioner for testing
@ -127,7 +130,7 @@ func (m *MockProvisioner) GetName() string {
return m.Mret1.(string)
}
// AuthorizeOrderIdentifiers mock
// AuthorizeOrderIdentifier mock
func (m *MockProvisioner) AuthorizeOrderIdentifier(ctx context.Context, identifier provisioner.ACMEIdentifier) error {
if m.MauthorizeOrderIdentifier != nil {
return m.MauthorizeOrderIdentifier(ctx, identifier)

@ -2,6 +2,7 @@ package acme
import (
"context"
"database/sql"
"github.com/pkg/errors"
)
@ -12,6 +13,12 @@ import (
// account.
var ErrNotFound = errors.New("not found")
// IsErrNotFound returns true if the error is a "not found" error. Returns false
// otherwise.
func IsErrNotFound(err error) bool {
return errors.Is(err, ErrNotFound) || errors.Is(err, sql.ErrNoRows)
}
// DB is the DB interface expected by the step-ca ACME API.
type DB interface {
CreateAccount(ctx context.Context, acc *Account) error
@ -65,11 +72,14 @@ func DatabaseFromContext(ctx context.Context) (db DB, ok bool) {
// MustDatabaseFromContext returns the current database from the given context.
// It will panic if it's not in the context.
func MustDatabaseFromContext(ctx context.Context) DB {
if db, ok := DatabaseFromContext(ctx); !ok {
var (
db DB
ok bool
)
if db, ok = DatabaseFromContext(ctx); !ok {
panic("acme database is not in the context")
} else {
return db
}
return db
}
// MockDB is an implementation of the DB interface that should only be used as

@ -13,12 +13,15 @@ import (
// dbAccount represents an ACME account.
type dbAccount struct {
ID string `json:"id"`
Key *jose.JSONWebKey `json:"key"`
Contact []string `json:"contact,omitempty"`
Status acme.Status `json:"status"`
CreatedAt time.Time `json:"createdAt"`
DeactivatedAt time.Time `json:"deactivatedAt"`
ID string `json:"id"`
Key *jose.JSONWebKey `json:"key"`
Contact []string `json:"contact,omitempty"`
Status acme.Status `json:"status"`
LocationPrefix string `json:"locationPrefix"`
ProvisionerID string `json:"provisionerID,omitempty"`
ProvisionerName string `json:"provisionerName"`
CreatedAt time.Time `json:"createdAt"`
DeactivatedAt time.Time `json:"deactivatedAt"`
}
func (dba *dbAccount) clone() *dbAccount {
@ -26,7 +29,7 @@ func (dba *dbAccount) clone() *dbAccount {
return &nu
}
func (db *DB) getAccountIDByKeyID(ctx context.Context, kid string) (string, error) {
func (db *DB) getAccountIDByKeyID(_ context.Context, kid string) (string, error) {
id, err := db.db.Get(accountByKeyIDTable, []byte(kid))
if err != nil {
if nosqlDB.IsErrNotFound(err) {
@ -38,7 +41,7 @@ func (db *DB) getAccountIDByKeyID(ctx context.Context, kid string) (string, erro
}
// getDBAccount retrieves and unmarshals dbAccount.
func (db *DB) getDBAccount(ctx context.Context, id string) (*dbAccount, error) {
func (db *DB) getDBAccount(_ context.Context, id string) (*dbAccount, error) {
data, err := db.db.Get(accountTable, []byte(id))
if err != nil {
if nosqlDB.IsErrNotFound(err) {
@ -62,10 +65,13 @@ func (db *DB) GetAccount(ctx context.Context, id string) (*acme.Account, error)
}
return &acme.Account{
Status: dbacc.Status,
Contact: dbacc.Contact,
Key: dbacc.Key,
ID: dbacc.ID,
Status: dbacc.Status,
Contact: dbacc.Contact,
Key: dbacc.Key,
ID: dbacc.ID,
LocationPrefix: dbacc.LocationPrefix,
ProvisionerID: dbacc.ProvisionerID,
ProvisionerName: dbacc.ProvisionerName,
}, nil
}
@ -87,11 +93,14 @@ func (db *DB) CreateAccount(ctx context.Context, acc *acme.Account) error {
}
dba := &dbAccount{
ID: acc.ID,
Key: acc.Key,
Contact: acc.Contact,
Status: acc.Status,
CreatedAt: clock.Now(),
ID: acc.ID,
Key: acc.Key,
Contact: acc.Contact,
Status: acc.Status,
CreatedAt: clock.Now(),
LocationPrefix: acc.LocationPrefix,
ProvisionerID: acc.ProvisionerID,
ProvisionerName: acc.ProvisionerName,
}
kid, err := acme.KeyToID(dba.Key)

@ -68,12 +68,14 @@ func TestDB_getDBAccount(t *testing.T) {
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
assert.FatalError(t, err)
dbacc := &dbAccount{
ID: accID,
Status: acme.StatusDeactivated,
CreatedAt: now,
DeactivatedAt: now,
Contact: []string{"foo", "bar"},
Key: jwk,
ID: accID,
Status: acme.StatusDeactivated,
CreatedAt: now,
DeactivatedAt: now,
Contact: []string{"foo", "bar"},
Key: jwk,
ProvisionerID: "73d2c0f1-9753-448b-9b48-bf00fe434681",
ProvisionerName: "acme",
}
b, err := json.Marshal(dbacc)
assert.FatalError(t, err)
@ -197,6 +199,8 @@ func TestDB_getAccountIDByKeyID(t *testing.T) {
func TestDB_GetAccount(t *testing.T) {
accID := "accID"
locationPrefix := "https://test.ca.smallstep.com/acme/foo/account/"
provisionerName := "foo"
type test struct {
db nosql.DB
err error
@ -222,12 +226,14 @@ func TestDB_GetAccount(t *testing.T) {
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
assert.FatalError(t, err)
dbacc := &dbAccount{
ID: accID,
Status: acme.StatusDeactivated,
CreatedAt: now,
DeactivatedAt: now,
Contact: []string{"foo", "bar"},
Key: jwk,
ID: accID,
Status: acme.StatusDeactivated,
CreatedAt: now,
DeactivatedAt: now,
Contact: []string{"foo", "bar"},
Key: jwk,
LocationPrefix: locationPrefix,
ProvisionerName: provisionerName,
}
b, err := json.Marshal(dbacc)
assert.FatalError(t, err)
@ -266,6 +272,8 @@ func TestDB_GetAccount(t *testing.T) {
assert.Equals(t, acc.ID, tc.dbacc.ID)
assert.Equals(t, acc.Status, tc.dbacc.Status)
assert.Equals(t, acc.Contact, tc.dbacc.Contact)
assert.Equals(t, acc.LocationPrefix, tc.dbacc.LocationPrefix)
assert.Equals(t, acc.ProvisionerName, tc.dbacc.ProvisionerName)
assert.Equals(t, acc.Key.KeyID, tc.dbacc.Key.KeyID)
}
})
@ -379,6 +387,7 @@ func TestDB_GetAccountByKeyID(t *testing.T) {
}
func TestDB_CreateAccount(t *testing.T) {
locationPrefix := "https://test.ca.smallstep.com/acme/foo/account/"
type test struct {
db nosql.DB
acc *acme.Account
@ -390,9 +399,10 @@ func TestDB_CreateAccount(t *testing.T) {
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
assert.FatalError(t, err)
acc := &acme.Account{
Status: acme.StatusValid,
Contact: []string{"foo", "bar"},
Key: jwk,
Status: acme.StatusValid,
Contact: []string{"foo", "bar"},
Key: jwk,
LocationPrefix: locationPrefix,
}
return test{
db: &db.MockNoSQLDB{
@ -413,9 +423,10 @@ func TestDB_CreateAccount(t *testing.T) {
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
assert.FatalError(t, err)
acc := &acme.Account{
Status: acme.StatusValid,
Contact: []string{"foo", "bar"},
Key: jwk,
Status: acme.StatusValid,
Contact: []string{"foo", "bar"},
Key: jwk,
LocationPrefix: locationPrefix,
}
return test{
db: &db.MockNoSQLDB{
@ -436,9 +447,10 @@ func TestDB_CreateAccount(t *testing.T) {
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
assert.FatalError(t, err)
acc := &acme.Account{
Status: acme.StatusValid,
Contact: []string{"foo", "bar"},
Key: jwk,
Status: acme.StatusValid,
Contact: []string{"foo", "bar"},
Key: jwk,
LocationPrefix: locationPrefix,
}
return test{
db: &db.MockNoSQLDB{
@ -456,6 +468,8 @@ func TestDB_CreateAccount(t *testing.T) {
assert.FatalError(t, json.Unmarshal(nu, dbacc))
assert.Equals(t, dbacc.ID, string(key))
assert.Equals(t, dbacc.Contact, acc.Contact)
assert.Equals(t, dbacc.LocationPrefix, acc.LocationPrefix)
assert.Equals(t, dbacc.ProvisionerName, acc.ProvisionerName)
assert.Equals(t, dbacc.Key.KeyID, acc.Key.KeyID)
assert.True(t, clock.Now().Add(-time.Minute).Before(dbacc.CreatedAt))
assert.True(t, clock.Now().Add(time.Minute).After(dbacc.CreatedAt))
@ -479,9 +493,10 @@ func TestDB_CreateAccount(t *testing.T) {
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
assert.FatalError(t, err)
acc := &acme.Account{
Status: acme.StatusValid,
Contact: []string{"foo", "bar"},
Key: jwk,
Status: acme.StatusValid,
Contact: []string{"foo", "bar"},
Key: jwk,
LocationPrefix: locationPrefix,
}
return test{
db: &db.MockNoSQLDB{
@ -500,6 +515,8 @@ func TestDB_CreateAccount(t *testing.T) {
assert.FatalError(t, json.Unmarshal(nu, dbacc))
assert.Equals(t, dbacc.ID, string(key))
assert.Equals(t, dbacc.Contact, acc.Contact)
assert.Equals(t, dbacc.LocationPrefix, acc.LocationPrefix)
assert.Equals(t, dbacc.ProvisionerName, acc.ProvisionerName)
assert.Equals(t, dbacc.Key.KeyID, acc.Key.KeyID)
assert.True(t, clock.Now().Add(-time.Minute).Before(dbacc.CreatedAt))
assert.True(t, clock.Now().Add(time.Minute).After(dbacc.CreatedAt))
@ -539,12 +556,14 @@ func TestDB_UpdateAccount(t *testing.T) {
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
assert.FatalError(t, err)
dbacc := &dbAccount{
ID: accID,
Status: acme.StatusDeactivated,
CreatedAt: now,
DeactivatedAt: now,
Contact: []string{"foo", "bar"},
Key: jwk,
ID: accID,
Status: acme.StatusDeactivated,
CreatedAt: now,
DeactivatedAt: now,
Contact: []string{"foo", "bar"},
LocationPrefix: "foo",
ProvisionerName: "alpha",
Key: jwk,
}
b, err := json.Marshal(dbacc)
assert.FatalError(t, err)
@ -644,10 +663,12 @@ func TestDB_UpdateAccount(t *testing.T) {
},
"ok": func(t *testing.T) test {
acc := &acme.Account{
ID: accID,
Status: acme.StatusDeactivated,
Contact: []string{"foo", "bar"},
Key: jwk,
ID: accID,
Status: acme.StatusDeactivated,
Contact: []string{"baz", "zap"},
LocationPrefix: "bar",
ProvisionerName: "beta",
Key: jwk,
}
return test{
acc: acc,
@ -666,7 +687,10 @@ func TestDB_UpdateAccount(t *testing.T) {
assert.FatalError(t, json.Unmarshal(nu, dbNew))
assert.Equals(t, dbNew.ID, dbacc.ID)
assert.Equals(t, dbNew.Status, acc.Status)
assert.Equals(t, dbNew.Contact, dbacc.Contact)
assert.Equals(t, dbNew.Contact, acc.Contact)
// LocationPrefix should not change.
assert.Equals(t, dbNew.LocationPrefix, dbacc.LocationPrefix)
assert.Equals(t, dbNew.ProvisionerName, dbacc.ProvisionerName)
assert.Equals(t, dbNew.Key.KeyID, dbacc.Key.KeyID)
assert.Equals(t, dbNew.CreatedAt, dbacc.CreatedAt)
assert.True(t, dbNew.DeactivatedAt.Add(-time.Minute).Before(now))
@ -686,12 +710,7 @@ func TestDB_UpdateAccount(t *testing.T) {
assert.HasPrefix(t, err.Error(), tc.err.Error())
}
} else {
if assert.Nil(t, tc.err) {
assert.Equals(t, tc.acc.ID, dbacc.ID)
assert.Equals(t, tc.acc.Status, dbacc.Status)
assert.Equals(t, tc.acc.Contact, dbacc.Contact)
assert.Equals(t, tc.acc.Key.KeyID, dbacc.Key.KeyID)
}
assert.Nil(t, tc.err)
}
})
}

@ -17,6 +17,7 @@ type dbAuthz struct {
Identifier acme.Identifier `json:"identifier"`
Status acme.Status `json:"status"`
Token string `json:"token"`
Fingerprint string `json:"fingerprint,omitempty"`
ChallengeIDs []string `json:"challengeIDs"`
Wildcard bool `json:"wildcard"`
CreatedAt time.Time `json:"createdAt"`
@ -31,7 +32,7 @@ func (ba *dbAuthz) clone() *dbAuthz {
// getDBAuthz retrieves and unmarshals a database representation of the
// ACME Authorization type.
func (db *DB) getDBAuthz(ctx context.Context, id string) (*dbAuthz, error) {
func (db *DB) getDBAuthz(_ context.Context, id string) (*dbAuthz, error) {
data, err := db.db.Get(authzTable, []byte(id))
if nosql.IsErrNotFound(err) {
return nil, acme.NewError(acme.ErrorMalformedType, "authz %s not found", id)
@ -61,15 +62,16 @@ func (db *DB) GetAuthorization(ctx context.Context, id string) (*acme.Authorizat
}
}
return &acme.Authorization{
ID: dbaz.ID,
AccountID: dbaz.AccountID,
Identifier: dbaz.Identifier,
Status: dbaz.Status,
Challenges: chs,
Wildcard: dbaz.Wildcard,
ExpiresAt: dbaz.ExpiresAt,
Token: dbaz.Token,
Error: dbaz.Error,
ID: dbaz.ID,
AccountID: dbaz.AccountID,
Identifier: dbaz.Identifier,
Status: dbaz.Status,
Challenges: chs,
Wildcard: dbaz.Wildcard,
ExpiresAt: dbaz.ExpiresAt,
Token: dbaz.Token,
Fingerprint: dbaz.Fingerprint,
Error: dbaz.Error,
}, nil
}
@ -97,6 +99,7 @@ func (db *DB) CreateAuthorization(ctx context.Context, az *acme.Authorization) e
Identifier: az.Identifier,
ChallengeIDs: chIDs,
Token: az.Token,
Fingerprint: az.Fingerprint,
Wildcard: az.Wildcard,
}
@ -111,14 +114,14 @@ func (db *DB) UpdateAuthorization(ctx context.Context, az *acme.Authorization) e
}
nu := old.clone()
nu.Status = az.Status
nu.Fingerprint = az.Fingerprint
nu.Error = az.Error
return db.save(ctx, old.ID, nu, old, "authz", authzTable)
}
// GetAuthorizationsByAccountID retrieves and unmarshals ACME authz types from the database.
func (db *DB) GetAuthorizationsByAccountID(ctx context.Context, accountID string) ([]*acme.Authorization, error) {
func (db *DB) GetAuthorizationsByAccountID(_ context.Context, accountID string) ([]*acme.Authorization, error) {
entries, err := db.db.List(authzTable)
if err != nil {
return nil, errors.Wrapf(err, "error listing authz")
@ -136,15 +139,16 @@ func (db *DB) GetAuthorizationsByAccountID(ctx context.Context, accountID string
continue
}
authzs = append(authzs, &acme.Authorization{
ID: dbaz.ID,
AccountID: dbaz.AccountID,
Identifier: dbaz.Identifier,
Status: dbaz.Status,
Challenges: nil, // challenges not required for current use case
Wildcard: dbaz.Wildcard,
ExpiresAt: dbaz.ExpiresAt,
Token: dbaz.Token,
Error: dbaz.Error,
ID: dbaz.ID,
AccountID: dbaz.AccountID,
Identifier: dbaz.Identifier,
Status: dbaz.Status,
Challenges: nil, // challenges not required for current use case
Wildcard: dbaz.Wildcard,
ExpiresAt: dbaz.ExpiresAt,
Token: dbaz.Token,
Fingerprint: dbaz.Fingerprint,
Error: dbaz.Error,
})
}

@ -473,6 +473,7 @@ func TestDB_UpdateAuthorization(t *testing.T) {
ExpiresAt: now.Add(5 * time.Minute),
ChallengeIDs: []string{"foo", "bar"},
Wildcard: true,
Fingerprint: "fingerprint",
}
b, err := json.Marshal(dbaz)
assert.FatalError(t, err)
@ -549,10 +550,11 @@ func TestDB_UpdateAuthorization(t *testing.T) {
{ID: "foo"},
{ID: "bar"},
},
Token: dbaz.Token,
Wildcard: dbaz.Wildcard,
ExpiresAt: dbaz.ExpiresAt,
Error: acme.NewError(acme.ErrorMalformedType, "malformed"),
Token: dbaz.Token,
Wildcard: dbaz.Wildcard,
ExpiresAt: dbaz.ExpiresAt,
Fingerprint: "fingerprint",
Error: acme.NewError(acme.ErrorMalformedType, "malformed"),
}
return test{
az: updAz,
@ -582,6 +584,7 @@ func TestDB_UpdateAuthorization(t *testing.T) {
assert.Equals(t, dbNew.Wildcard, dbaz.Wildcard)
assert.Equals(t, dbNew.CreatedAt, dbaz.CreatedAt)
assert.Equals(t, dbNew.ExpiresAt, dbaz.ExpiresAt)
assert.Equals(t, dbNew.Fingerprint, dbaz.Fingerprint)
assert.Equals(t, dbNew.Error.Error(), acme.NewError(acme.ErrorMalformedType, "The request message was malformed").Error())
return nu, true, nil
},

@ -69,7 +69,7 @@ func (db *DB) CreateCertificate(ctx context.Context, cert *acme.Certificate) err
// GetCertificate retrieves and unmarshals an ACME certificate type from the
// datastore.
func (db *DB) GetCertificate(ctx context.Context, id string) (*acme.Certificate, error) {
func (db *DB) GetCertificate(_ context.Context, id string) (*acme.Certificate, error) {
b, err := db.db.Get(certTable, []byte(id))
if nosql.IsErrNotFound(err) {
return nil, acme.NewError(acme.ErrorMalformedType, "certificate %s not found", id)

@ -6,8 +6,10 @@ import (
"time"
"github.com/pkg/errors"
"github.com/smallstep/certificates/acme"
"github.com/smallstep/nosql"
"github.com/smallstep/certificates/acme"
)
type dbChallenge struct {
@ -19,7 +21,7 @@ type dbChallenge struct {
Value string `json:"value"`
ValidatedAt string `json:"validatedAt"`
CreatedAt time.Time `json:"createdAt"`
Error *acme.Error `json:"error"`
Error *acme.Error `json:"error"` // TODO(hs): a bit dangerous; should become db-specific type
}
func (dbc *dbChallenge) clone() *dbChallenge {
@ -27,7 +29,7 @@ func (dbc *dbChallenge) clone() *dbChallenge {
return &u
}
func (db *DB) getDBChallenge(ctx context.Context, id string) (*dbChallenge, error) {
func (db *DB) getDBChallenge(_ context.Context, id string) (*dbChallenge, error) {
data, err := db.db.Get(challengeTable, []byte(id))
if nosql.IsErrNotFound(err) {
return nil, acme.NewError(acme.ErrorMalformedType, "challenge %s not found", id)
@ -67,6 +69,7 @@ func (db *DB) CreateChallenge(ctx context.Context, ch *acme.Challenge) error {
// GetChallenge retrieves and unmarshals an ACME challenge type from the database.
// Implements the acme.DB GetChallenge interface.
func (db *DB) GetChallenge(ctx context.Context, id, authzID string) (*acme.Challenge, error) {
_ = authzID // unused input
dbch, err := db.getDBChallenge(ctx, id)
if err != nil {
return nil, err

@ -35,7 +35,7 @@ type dbExternalAccountKeyReference struct {
}
// getDBExternalAccountKey retrieves and unmarshals dbExternalAccountKey.
func (db *DB) getDBExternalAccountKey(ctx context.Context, id string) (*dbExternalAccountKey, error) {
func (db *DB) getDBExternalAccountKey(_ context.Context, id string) (*dbExternalAccountKey, error) {
data, err := db.db.Get(externalAccountKeyTable, []byte(id))
if err != nil {
if nosqlDB.IsErrNotFound(err) {
@ -160,6 +160,8 @@ func (db *DB) DeleteExternalAccountKey(ctx context.Context, provisionerID, keyID
// GetExternalAccountKeys retrieves all External Account Binding keys for a provisioner
func (db *DB) GetExternalAccountKeys(ctx context.Context, provisionerID, cursor string, limit int) ([]*acme.ExternalAccountKey, string, error) {
_, _ = cursor, limit // unused input
externalAccountKeyMutex.RLock()
defer externalAccountKeyMutex.RUnlock()
@ -227,7 +229,7 @@ func (db *DB) GetExternalAccountKeyByReference(ctx context.Context, provisionerI
return db.GetExternalAccountKey(ctx, provisionerID, dbExternalAccountKeyReference.ExternalAccountKeyID)
}
func (db *DB) GetExternalAccountKeyByAccountID(ctx context.Context, provisionerID, accountID string) (*acme.ExternalAccountKey, error) {
func (db *DB) GetExternalAccountKeyByAccountID(context.Context, string, string) (*acme.ExternalAccountKey, error) {
//nolint:nilnil // legacy
return nil, nil
}

@ -39,7 +39,7 @@ func (db *DB) CreateNonce(ctx context.Context) (acme.Nonce, error) {
// DeleteNonce verifies that the nonce is valid (by checking if it exists),
// and if so, consumes the nonce resource by deleting it from the database.
func (db *DB) DeleteNonce(ctx context.Context, nonce acme.Nonce) error {
func (db *DB) DeleteNonce(_ context.Context, nonce acme.Nonce) error {
err := db.db.Update(&database.Tx{
Operations: []*database.TxEntry{
{

@ -48,7 +48,7 @@ func New(db nosqlDB.DB) (*DB, error) {
// save writes the new data to the database, overwriting the old data if it
// existed.
func (db *DB) save(ctx context.Context, id string, nu, old interface{}, typ string, table []byte) error {
func (db *DB) save(_ context.Context, id string, nu, old interface{}, typ string, table []byte) error {
var (
err error
newB []byte

@ -35,7 +35,7 @@ func (a *dbOrder) clone() *dbOrder {
}
// getDBOrder retrieves and unmarshals an ACME Order type from the database.
func (db *DB) getDBOrder(ctx context.Context, id string) (*dbOrder, error) {
func (db *DB) getDBOrder(_ context.Context, id string) (*dbOrder, error) {
b, err := db.db.Get(orderTable, []byte(id))
if nosql.IsErrNotFound(err) {
return nil, acme.NewError(acme.ErrorMalformedType, "order %s not found", id)

@ -0,0 +1,32 @@
package acme
import (
"database/sql"
"errors"
"fmt"
"testing"
)
func TestIsErrNotFound(t *testing.T) {
type args struct {
err error
}
tests := []struct {
name string
args args
want bool
}{
{"true ErrNotFound", args{ErrNotFound}, true},
{"true sql.ErrNoRows", args{sql.ErrNoRows}, true},
{"true wrapped ErrNotFound", args{fmt.Errorf("something failed: %w", ErrNotFound)}, true},
{"true wrapped sql.ErrNoRows", args{fmt.Errorf("something failed: %w", sql.ErrNoRows)}, true},
{"false other", args{errors.New("not found")}, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := IsErrNotFound(tt.args.err); got != tt.want {
t.Errorf("IsErrNotFound() = %v, want %v", got, tt.want)
}
})
}
}

@ -270,21 +270,77 @@ var (
}
)
// Error represents an ACME
// Error represents an ACME Error
type Error struct {
Type string `json:"type"`
Detail string `json:"detail"`
Subproblems []interface{} `json:"subproblems,omitempty"`
Identifier interface{} `json:"identifier,omitempty"`
Err error `json:"-"`
Status int `json:"-"`
Type string `json:"type"`
Detail string `json:"detail"`
Subproblems []Subproblem `json:"subproblems,omitempty"`
Err error `json:"-"`
Status int `json:"-"`
}
// NewError creates a new Error type.
// Subproblem represents an ACME subproblem. It's fairly
// similar to an ACME error, but differs in that it can't
// include subproblems itself, the error is reflected
// in the Detail property and doesn't have a Status.
type Subproblem struct {
Type string `json:"type"`
Detail string `json:"detail"`
// The "identifier" field MUST NOT be present at the top level in ACME
// problem documents. It can only be present in subproblems.
// Subproblems need not all have the same type, and they do not need to
// match the top level type.
Identifier *Identifier `json:"identifier,omitempty"`
}
// NewError creates a new Error.
func NewError(pt ProblemType, msg string, args ...interface{}) *Error {
return newError(pt, errors.Errorf(msg, args...))
}
// NewDetailedError creates a new Error that includes the error
// message in the details, providing more information to the
// ACME client.
func NewDetailedError(pt ProblemType, msg string, args ...interface{}) *Error {
return NewError(pt, msg, args...).withDetail()
}
func (e *Error) withDetail() *Error {
if e == nil || e.Status >= 500 || e.Err == nil {
return e
}
e.Detail = fmt.Sprintf("%s: %s", e.Detail, e.Err)
return e
}
// AddSubproblems adds the Subproblems to Error. It
// returns the Error, allowing for fluent addition.
func (e *Error) AddSubproblems(subproblems ...Subproblem) *Error {
e.Subproblems = append(e.Subproblems, subproblems...)
return e
}
// NewSubproblem creates a new Subproblem. The msg and args
// are used to create a new error, which is set as the Detail, allowing
// for more detailed error messages to be returned to the ACME client.
func NewSubproblem(pt ProblemType, msg string, args ...interface{}) Subproblem {
e := newError(pt, fmt.Errorf(msg, args...))
s := Subproblem{
Type: e.Type,
Detail: e.Err.Error(),
}
return s
}
// NewSubproblemWithIdentifier creates a new Subproblem with a specific ACME
// Identifier. It calls NewSubproblem and sets the Identifier.
func NewSubproblemWithIdentifier(pt ProblemType, identifier Identifier, msg string, args ...interface{}) Subproblem {
s := NewSubproblem(pt, msg, args...)
s.Identifier = &identifier
return s
}
func newError(pt ProblemType, err error) *Error {
meta, ok := errorMap[pt]
if !ok {
@ -328,6 +384,10 @@ func WrapError(typ ProblemType, err error, msg string, args ...interface{}) *Err
}
}
func WrapDetailedError(typ ProblemType, err error, msg string, args ...interface{}) *Error {
return WrapError(typ, err, msg, args...).withDetail()
}
// WrapErrorISE shortcut to wrap an internal server error type.
func WrapErrorISE(err error, msg string, args ...interface{}) *Error {
return WrapError(ErrorServerInternalType, err, msg, args...)
@ -364,7 +424,7 @@ func (e *Error) ToLog() (interface{}, error) {
}
// Render implements render.RenderableError for Error.
func (e *Error) Render(w http.ResponseWriter) {
func (e *Error) Render(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/problem+json")
render.JSONStatus(w, e, e.StatusCode())
render.JSONStatus(w, r, e, e.StatusCode())
}

@ -0,0 +1,54 @@
package acme
import (
"encoding/json"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func mustJSON(t *testing.T, m map[string]interface{}) string {
t.Helper()
b, err := json.Marshal(m)
require.NoError(t, err)
return string(b)
}
func TestError_WithAdditionalErrorDetail(t *testing.T) {
internalJSON := mustJSON(t, map[string]interface{}{
"detail": "The server experienced an internal error",
"type": "urn:ietf:params:acme:error:serverInternal",
})
malformedErr := NewError(ErrorMalformedType, "malformed error") // will result in Err == nil behavior
malformedJSON := mustJSON(t, map[string]interface{}{
"detail": "The request message was malformed",
"type": "urn:ietf:params:acme:error:malformed",
})
withDetailJSON := mustJSON(t, map[string]interface{}{
"detail": "Attestation statement cannot be verified: invalid property",
"type": "urn:ietf:params:acme:error:badAttestationStatement",
})
tests := []struct {
name string
err *Error
want string
}{
{"internal", NewDetailedError(ErrorServerInternalType, ""), internalJSON},
{"nil err", malformedErr, malformedJSON},
{"detailed", NewDetailedError(ErrorBadAttestationStatementType, "invalid property"), withDetailJSON},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
b, err := json.Marshal(tt.err)
require.NoError(t, err)
// tests if the additional error detail is included in the JSON representation
// of the ACME error. This is what is returned to ACME clients and being logged
// by the CA.
assert.JSONEq(t, tt.want, string(b))
})
}
}

@ -8,7 +8,7 @@ import (
"net/url"
"strings"
"github.com/go-chi/chi"
"github.com/go-chi/chi/v5"
"github.com/smallstep/certificates/api/render"
"github.com/smallstep/certificates/authority"
"github.com/smallstep/certificates/authority/provisioner"
@ -142,11 +142,14 @@ func LinkerFromContext(ctx context.Context) (v Linker, ok bool) {
// MustLinkerFromContext returns the current linker from the given context. It
// will panic if it's not in the context.
func MustLinkerFromContext(ctx context.Context) Linker {
if v, ok := LinkerFromContext(ctx); !ok {
var (
v Linker
ok bool
)
if v, ok = LinkerFromContext(ctx); !ok {
panic("acme linker is not the context")
} else {
return v
}
return v
}
type baseURLKey struct{}
@ -183,19 +186,19 @@ func (l *linker) Middleware(next http.Handler) http.Handler {
nameEscaped := chi.URLParam(r, "provisionerID")
name, err := url.PathUnescape(nameEscaped)
if err != nil {
render.Error(w, WrapErrorISE(err, "error url unescaping provisioner name '%s'", nameEscaped))
render.Error(w, r, WrapErrorISE(err, "error url unescaping provisioner name '%s'", nameEscaped))
return
}
p, err := authority.MustFromContext(ctx).LoadProvisionerByName(name)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
acmeProv, ok := p.(*provisioner.ACME)
if !ok {
render.Error(w, NewError(ErrorAccountDoesNotExistType, "provisioner must be of type ACME"))
render.Error(w, r, NewError(ErrorAccountDoesNotExistType, "provisioner must be of type ACME"))
return
}

@ -3,6 +3,7 @@ package acme
import (
"bytes"
"context"
"crypto/subtle"
"crypto/x509"
"encoding/json"
"net"
@ -11,6 +12,7 @@ import (
"time"
"github.com/smallstep/certificates/authority/provisioner"
"go.step.sm/crypto/keyutil"
"go.step.sm/crypto/x509util"
)
@ -125,6 +127,27 @@ func (o *Order) UpdateStatus(ctx context.Context, db DB) error {
return nil
}
// getAuthorizationFingerprint returns a fingerprint from the list of authorizations. This
// fingerprint is used on the device-attest-01 flow to verify the attestation
// certificate public key with the CSR public key.
//
// There's no point on reading all the authorizations as there will be only one
// for a permanent identifier.
func (o *Order) getAuthorizationFingerprint(ctx context.Context, db DB) (string, error) {
for _, azID := range o.AuthorizationIDs {
az, err := db.GetAuthorization(ctx, azID)
if err != nil {
return "", WrapErrorISE(err, "error getting authorization %q", azID)
}
// There's no point on reading all the authorizations as there will
// be only one for a permanent identifier.
if az.Fingerprint != "" {
return az.Fingerprint, nil
}
}
return "", nil
}
// Finalize signs a certificate if the necessary conditions for Order completion
// have been met.
//
@ -150,6 +173,24 @@ func (o *Order) Finalize(ctx context.Context, db DB, csr *x509.CertificateReques
return NewErrorISE("unexpected status %s for order %s", o.Status, o.ID)
}
// Get key fingerprint if any. And then compare it with the CSR fingerprint.
//
// In device-attest-01 challenges we should check that the keys in the CSR
// and the attestation certificate are the same.
fingerprint, err := o.getAuthorizationFingerprint(ctx, db)
if err != nil {
return err
}
if fingerprint != "" {
fp, err := keyutil.Fingerprint(csr.PublicKey)
if err != nil {
return WrapErrorISE(err, "error calculating key fingerprint")
}
if subtle.ConstantTimeCompare([]byte(fingerprint), []byte(fp)) == 0 {
return NewError(ErrorUnauthorizedType, "order %s csr does not match the attested key", o.ID)
}
}
// canonicalize the CSR to allow for comparison
csr = canonicalize(csr)
@ -165,6 +206,15 @@ func (o *Order) Finalize(ctx context.Context, db DB, csr *x509.CertificateReques
for i := range o.Identifiers {
if o.Identifiers[i].Type == PermanentIdentifier {
permanentIdentifier = o.Identifiers[i].Value
// the first (and only) Permanent Identifier that gets added to the certificate
// should be equal to the Subject Common Name if it's set. If not equal, the CSR
// is rejected, because the Common Name hasn't been challenged in that case. This
// could result in unauthorized access if a relying system relies on the Common
// Name in its authorization logic.
if csr.Subject.CommonName != "" && csr.Subject.CommonName != permanentIdentifier {
return NewError(ErrorBadCSRType, "CSR Subject Common Name does not match identifiers exactly: "+
"CSR Subject Common Name = %s, Order Permanent Identifier = %s", csr.Subject.CommonName, permanentIdentifier)
}
break
}
}
@ -213,7 +263,7 @@ func (o *Order) Finalize(ctx context.Context, db DB, csr *x509.CertificateReques
signOps = append(signOps, extraOptions...)
// Sign a new certificate.
certChain, err := auth.Sign(csr, provisioner.SignOptions{
certChain, err := auth.SignWithContext(ctx, csr, provisioner.SignOptions{
NotBefore: provisioner.NewTimeDuration(o.NotBefore),
NotAfter: provisioner.NewTimeDuration(o.NotAfter),
}, signOps...)

@ -2,9 +2,12 @@ package acme
import (
"context"
"crypto"
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
"encoding/json"
"fmt"
"net"
"net/url"
"reflect"
@ -16,6 +19,7 @@ import (
"github.com/smallstep/assert"
"github.com/smallstep/certificates/authority"
"github.com/smallstep/certificates/authority/provisioner"
"go.step.sm/crypto/keyutil"
"go.step.sm/crypto/x509util"
)
@ -267,16 +271,16 @@ func TestOrder_UpdateStatus(t *testing.T) {
}
type mockSignAuth struct {
sign func(csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error)
signWithContext func(ctx context.Context, csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error)
areSANsAllowed func(ctx context.Context, sans []string) error
loadProvisionerByName func(string) (provisioner.Interface, error)
ret1, ret2 interface{}
err error
}
func (m *mockSignAuth) Sign(csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
if m.sign != nil {
return m.sign(csr, signOpts, extraOpts...)
func (m *mockSignAuth) SignWithContext(ctx context.Context, csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
if m.signWithContext != nil {
return m.signWithContext(ctx, csr, signOpts, extraOpts...)
} else if m.err != nil {
return nil, m.err
}
@ -297,7 +301,7 @@ func (m *mockSignAuth) LoadProvisionerByName(name string) (provisioner.Interface
return m.ret1.(provisioner.Interface), m.err
}
func (m *mockSignAuth) IsRevoked(sn string) (bool, error) {
func (m *mockSignAuth) IsRevoked(string) (bool, error) {
return false, nil
}
@ -306,6 +310,14 @@ func (m *mockSignAuth) Revoke(context.Context, *authority.RevokeOptions) error {
}
func TestOrder_Finalize(t *testing.T) {
mustSigner := func(kty, crv string, size int) crypto.Signer {
s, err := keyutil.GenerateSigner(kty, crv, size)
if err != nil {
t.Fatal(err)
}
return s
}
type test struct {
o *Order
err *Error
@ -386,6 +398,72 @@ func TestOrder_Finalize(t *testing.T) {
err: NewErrorISE("unrecognized order status: %s", o.Status),
}
},
"fail/non-matching-permanent-identifier-common-name": func(t *testing.T) test {
now := clock.Now()
o := &Order{
ID: "oID",
AccountID: "accID",
Status: StatusReady,
ExpiresAt: now.Add(5 * time.Minute),
AuthorizationIDs: []string{"a", "b"},
Identifiers: []Identifier{
{Type: "permanent-identifier", Value: "a-permanent-identifier"},
},
}
signer := mustSigner("EC", "P-256", 0)
fingerprint, err := keyutil.Fingerprint(signer.Public())
if err != nil {
t.Fatal(err)
}
csr := &x509.CertificateRequest{
Subject: pkix.Name{
CommonName: "a-different-identifier",
},
PublicKey: signer.Public(),
ExtraExtensions: []pkix.Extension{
{
Id: asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 8, 3},
Value: []byte("a-permanent-identifier"),
},
},
}
return test{
o: o,
csr: csr,
db: &MockDB{
MockGetAuthorization: func(ctx context.Context, id string) (*Authorization, error) {
switch id {
case "a":
return &Authorization{
ID: id,
Status: StatusValid,
}, nil
case "b":
return &Authorization{
ID: id,
Fingerprint: fingerprint,
Status: StatusValid,
}, nil
default:
assert.FatalError(t, errors.Errorf("unexpected authorization %s", id))
return nil, errors.New("force")
}
},
MockUpdateOrder: func(ctx context.Context, o *Order) error {
return nil
},
},
err: &Error{
Type: "urn:ietf:params:acme:error:badCSR",
Detail: "The CSR is unacceptable",
Status: 400,
Err: fmt.Errorf("CSR Subject Common Name does not match identifiers exactly: "+
"CSR Subject Common Name = %s, Order Permanent Identifier = %s", csr.Subject.CommonName, "a-permanent-identifier"),
},
}
},
"fail/error-provisioner-auth": func(t *testing.T) test {
now := clock.Now()
o := &Order{
@ -415,6 +493,11 @@ func TestOrder_Finalize(t *testing.T) {
return nil, errors.New("force")
},
},
db: &MockDB{
MockGetAuthorization: func(ctx context.Context, id string) (*Authorization, error) {
return &Authorization{ID: id, Status: StatusValid}, nil
},
},
err: NewErrorISE("error retrieving authorization options from ACME provisioner: force"),
}
},
@ -454,6 +537,11 @@ func TestOrder_Finalize(t *testing.T) {
}
},
},
db: &MockDB{
MockGetAuthorization: func(ctx context.Context, id string) (*Authorization, error) {
return &Authorization{ID: id, Status: StatusValid}, nil
},
},
err: NewErrorISE("error creating template options from ACME provisioner: error unmarshaling template data: invalid character 'o' in literal false (expecting 'a')"),
}
},
@ -490,11 +578,16 @@ func TestOrder_Finalize(t *testing.T) {
},
},
ca: &mockSignAuth{
sign: func(_csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
signWithContext: func(_ context.Context, _csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
assert.Equals(t, _csr, csr)
return nil, errors.New("force")
},
},
db: &MockDB{
MockGetAuthorization: func(ctx context.Context, id string) (*Authorization, error) {
return &Authorization{ID: id, Status: StatusValid}, nil
},
},
err: NewErrorISE("error signing certificate for order oID: force"),
}
},
@ -535,12 +628,15 @@ func TestOrder_Finalize(t *testing.T) {
},
},
ca: &mockSignAuth{
sign: func(_csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
signWithContext: func(_ context.Context, _csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
assert.Equals(t, _csr, csr)
return []*x509.Certificate{foo, bar, baz}, nil
},
},
db: &MockDB{
MockGetAuthorization: func(ctx context.Context, id string) (*Authorization, error) {
return &Authorization{ID: id, Status: StatusValid}, nil
},
MockCreateCertificate: func(ctx context.Context, cert *Certificate) error {
assert.Equals(t, cert.AccountID, o.AccountID)
assert.Equals(t, cert.OrderID, o.ID)
@ -589,12 +685,15 @@ func TestOrder_Finalize(t *testing.T) {
},
},
ca: &mockSignAuth{
sign: func(_csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
signWithContext: func(_ context.Context, _csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
assert.Equals(t, _csr, csr)
return []*x509.Certificate{foo, bar, baz}, nil
},
},
db: &MockDB{
MockGetAuthorization: func(ctx context.Context, id string) (*Authorization, error) {
return &Authorization{ID: id, Status: StatusValid}, nil
},
MockCreateCertificate: func(ctx context.Context, cert *Certificate) error {
cert.ID = "certID"
assert.Equals(t, cert.AccountID, o.AccountID)
@ -617,6 +716,297 @@ func TestOrder_Finalize(t *testing.T) {
err: NewErrorISE("error updating order oID: force"),
}
},
"fail/csr-fingerprint": func(t *testing.T) test {
now := clock.Now()
o := &Order{
ID: "oID",
AccountID: "accID",
Status: StatusReady,
ExpiresAt: now.Add(5 * time.Minute),
AuthorizationIDs: []string{"a", "b"},
Identifiers: []Identifier{
{Type: "permanent-identifier", Value: "a-permanent-identifier"},
},
}
signer := mustSigner("EC", "P-256", 0)
csr := &x509.CertificateRequest{
Subject: pkix.Name{
CommonName: "a-permanent-identifier",
},
PublicKey: signer.Public(),
ExtraExtensions: []pkix.Extension{
{
Id: asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 8, 3},
Value: []byte("a-permanent-identifier"),
},
},
}
leaf := &x509.Certificate{
Subject: pkix.Name{CommonName: "a-permanent-identifier"},
PublicKey: signer.Public(),
ExtraExtensions: []pkix.Extension{
{
Id: asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 8, 3},
Value: []byte("a-permanent-identifier"),
},
},
}
inter := &x509.Certificate{Subject: pkix.Name{CommonName: "inter"}}
root := &x509.Certificate{Subject: pkix.Name{CommonName: "root"}}
return test{
o: o,
csr: csr,
prov: &MockProvisioner{
MauthorizeSign: func(ctx context.Context, token string) ([]provisioner.SignOption, error) {
assert.Equals(t, token, "")
return nil, nil
},
MgetOptions: func() *provisioner.Options {
return nil
},
},
ca: &mockSignAuth{
signWithContext: func(_ context.Context, _csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
assert.Equals(t, _csr, csr)
return []*x509.Certificate{leaf, inter, root}, nil
},
},
db: &MockDB{
MockGetAuthorization: func(ctx context.Context, id string) (*Authorization, error) {
return &Authorization{
ID: id,
Fingerprint: "other-fingerprint",
Status: StatusValid,
}, nil
},
MockCreateCertificate: func(ctx context.Context, cert *Certificate) error {
cert.ID = "certID"
assert.Equals(t, cert.AccountID, o.AccountID)
assert.Equals(t, cert.OrderID, o.ID)
assert.Equals(t, cert.Leaf, leaf)
assert.Equals(t, cert.Intermediates, []*x509.Certificate{inter, root})
return nil
},
MockUpdateOrder: func(ctx context.Context, updo *Order) error {
assert.Equals(t, updo.CertificateID, "certID")
assert.Equals(t, updo.Status, StatusValid)
assert.Equals(t, updo.ID, o.ID)
assert.Equals(t, updo.AccountID, o.AccountID)
assert.Equals(t, updo.ExpiresAt, o.ExpiresAt)
assert.Equals(t, updo.AuthorizationIDs, o.AuthorizationIDs)
assert.Equals(t, updo.Identifiers, o.Identifiers)
return nil
},
},
err: NewError(ErrorUnauthorizedType, "order oID csr does not match the attested key"),
}
},
"ok/permanent-identifier": func(t *testing.T) test {
now := clock.Now()
o := &Order{
ID: "oID",
AccountID: "accID",
Status: StatusReady,
ExpiresAt: now.Add(5 * time.Minute),
AuthorizationIDs: []string{"a", "b"},
Identifiers: []Identifier{
{Type: "permanent-identifier", Value: "a-permanent-identifier"},
},
}
signer := mustSigner("EC", "P-256", 0)
fingerprint, err := keyutil.Fingerprint(signer.Public())
if err != nil {
t.Fatal(err)
}
csr := &x509.CertificateRequest{
Subject: pkix.Name{
CommonName: "a-permanent-identifier",
},
PublicKey: signer.Public(),
ExtraExtensions: []pkix.Extension{
{
Id: asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 8, 3},
Value: []byte("a-permanent-identifier"),
},
},
}
leaf := &x509.Certificate{
Subject: pkix.Name{CommonName: "a-permanent-identifier"},
PublicKey: signer.Public(),
ExtraExtensions: []pkix.Extension{
{
Id: asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 8, 3},
Value: []byte("a-permanent-identifier"),
},
},
}
inter := &x509.Certificate{Subject: pkix.Name{CommonName: "inter"}}
root := &x509.Certificate{Subject: pkix.Name{CommonName: "root"}}
return test{
o: o,
csr: csr,
prov: &MockProvisioner{
MauthorizeSign: func(ctx context.Context, token string) ([]provisioner.SignOption, error) {
assert.Equals(t, token, "")
return nil, nil
},
MgetOptions: func() *provisioner.Options {
return nil
},
},
ca: &mockSignAuth{
signWithContext: func(_ context.Context, _csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
assert.Equals(t, _csr, csr)
return []*x509.Certificate{leaf, inter, root}, nil
},
},
db: &MockDB{
MockGetAuthorization: func(ctx context.Context, id string) (*Authorization, error) {
switch id {
case "a":
return &Authorization{
ID: id,
Status: StatusValid,
}, nil
case "b":
return &Authorization{
ID: id,
Fingerprint: fingerprint,
Status: StatusValid,
}, nil
default:
assert.FatalError(t, errors.Errorf("unexpected authorization %s", id))
return nil, errors.New("force")
}
},
MockCreateCertificate: func(ctx context.Context, cert *Certificate) error {
cert.ID = "certID"
assert.Equals(t, cert.AccountID, o.AccountID)
assert.Equals(t, cert.OrderID, o.ID)
assert.Equals(t, cert.Leaf, leaf)
assert.Equals(t, cert.Intermediates, []*x509.Certificate{inter, root})
return nil
},
MockUpdateOrder: func(ctx context.Context, updo *Order) error {
assert.Equals(t, updo.CertificateID, "certID")
assert.Equals(t, updo.Status, StatusValid)
assert.Equals(t, updo.ID, o.ID)
assert.Equals(t, updo.AccountID, o.AccountID)
assert.Equals(t, updo.ExpiresAt, o.ExpiresAt)
assert.Equals(t, updo.AuthorizationIDs, o.AuthorizationIDs)
assert.Equals(t, updo.Identifiers, o.Identifiers)
return nil
},
},
}
},
"ok/permanent-identifier-only": func(t *testing.T) test {
now := clock.Now()
o := &Order{
ID: "oID",
AccountID: "accID",
Status: StatusReady,
ExpiresAt: now.Add(5 * time.Minute),
AuthorizationIDs: []string{"a", "b"},
Identifiers: []Identifier{
{Type: "dns", Value: "foo.internal"},
{Type: "permanent-identifier", Value: "a-permanent-identifier"},
},
}
signer := mustSigner("EC", "P-256", 0)
fingerprint, err := keyutil.Fingerprint(signer.Public())
if err != nil {
t.Fatal(err)
}
csr := &x509.CertificateRequest{
Subject: pkix.Name{
CommonName: "a-permanent-identifier",
},
DNSNames: []string{"foo.internal"},
PublicKey: signer.Public(),
ExtraExtensions: []pkix.Extension{
{
Id: asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 8, 3},
Value: []byte("a-permanent-identifier"),
},
},
}
leaf := &x509.Certificate{
Subject: pkix.Name{CommonName: "a-permanent-identifier"},
PublicKey: signer.Public(),
ExtraExtensions: []pkix.Extension{
{
Id: asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 8, 3},
Value: []byte("a-permanent-identifier"),
},
},
}
inter := &x509.Certificate{Subject: pkix.Name{CommonName: "inter"}}
root := &x509.Certificate{Subject: pkix.Name{CommonName: "root"}}
return test{
o: o,
csr: csr,
prov: &MockProvisioner{
MauthorizeSign: func(ctx context.Context, token string) ([]provisioner.SignOption, error) {
assert.Equals(t, token, "")
return nil, nil
},
MgetOptions: func() *provisioner.Options {
return nil
},
},
// TODO(hs): we should work on making the mocks more realistic. Ideally, we should get rid of
// the mock entirely, relying on an instances of provisioner, authority and DB (possibly hardest), so
// that behavior of the tests is what an actual CA would do. We could gradually phase them out by
// using the mocking functions as a wrapper for actual test helpers generated per test case or per
// function that's tested.
ca: &mockSignAuth{
signWithContext: func(_ context.Context, _csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
assert.Equals(t, _csr, csr)
return []*x509.Certificate{leaf, inter, root}, nil
},
},
db: &MockDB{
MockGetAuthorization: func(ctx context.Context, id string) (*Authorization, error) {
return &Authorization{
ID: id,
Fingerprint: fingerprint,
Status: StatusValid,
}, nil
},
MockCreateCertificate: func(ctx context.Context, cert *Certificate) error {
cert.ID = "certID"
assert.Equals(t, cert.AccountID, o.AccountID)
assert.Equals(t, cert.OrderID, o.ID)
assert.Equals(t, cert.Leaf, leaf)
assert.Equals(t, cert.Intermediates, []*x509.Certificate{inter, root})
return nil
},
MockUpdateOrder: func(ctx context.Context, updo *Order) error {
assert.Equals(t, updo.CertificateID, "certID")
assert.Equals(t, updo.Status, StatusValid)
assert.Equals(t, updo.ID, o.ID)
assert.Equals(t, updo.AccountID, o.AccountID)
assert.Equals(t, updo.ExpiresAt, o.ExpiresAt)
assert.Equals(t, updo.AuthorizationIDs, o.AuthorizationIDs)
assert.Equals(t, updo.Identifiers, o.Identifiers)
return nil
},
},
}
},
"ok/new-cert-dns": func(t *testing.T) test {
now := clock.Now()
o := &Order{
@ -654,12 +1044,15 @@ func TestOrder_Finalize(t *testing.T) {
},
},
ca: &mockSignAuth{
sign: func(_csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
signWithContext: func(_ context.Context, _csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
assert.Equals(t, _csr, csr)
return []*x509.Certificate{foo, bar, baz}, nil
},
},
db: &MockDB{
MockGetAuthorization: func(ctx context.Context, id string) (*Authorization, error) {
return &Authorization{ID: id, Status: StatusValid}, nil
},
MockCreateCertificate: func(ctx context.Context, cert *Certificate) error {
cert.ID = "certID"
assert.Equals(t, cert.AccountID, o.AccountID)
@ -715,12 +1108,15 @@ func TestOrder_Finalize(t *testing.T) {
},
},
ca: &mockSignAuth{
sign: func(_csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
signWithContext: func(_ context.Context, _csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
assert.Equals(t, _csr, csr)
return []*x509.Certificate{foo, bar, baz}, nil
},
},
db: &MockDB{
MockGetAuthorization: func(ctx context.Context, id string) (*Authorization, error) {
return &Authorization{ID: id, Status: StatusValid}, nil
},
MockCreateCertificate: func(ctx context.Context, cert *Certificate) error {
cert.ID = "certID"
assert.Equals(t, cert.AccountID, o.AccountID)
@ -779,12 +1175,15 @@ func TestOrder_Finalize(t *testing.T) {
},
},
ca: &mockSignAuth{
sign: func(_csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
signWithContext: func(_ context.Context, _csr *x509.CertificateRequest, signOpts provisioner.SignOptions, extraOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
assert.Equals(t, _csr, csr)
return []*x509.Certificate{foo, bar, baz}, nil
},
},
db: &MockDB{
MockGetAuthorization: func(ctx context.Context, id string) (*Authorization, error) {
return &Authorization{ID: id, Status: StatusValid}, nil
},
MockCreateCertificate: func(ctx context.Context, cert *Certificate) error {
cert.ID = "certID"
assert.Equals(t, cert.AccountID, o.AccountID)
@ -1492,3 +1891,55 @@ func TestOrder_sans(t *testing.T) {
})
}
}
func TestOrder_getAuthorizationFingerprint(t *testing.T) {
ctx := context.Background()
type fields struct {
AuthorizationIDs []string
}
type args struct {
ctx context.Context
db DB
}
tests := []struct {
name string
fields fields
args args
want string
wantErr bool
}{
{"ok", fields{[]string{"az1", "az2"}}, args{ctx, &MockDB{
MockGetAuthorization: func(ctx context.Context, id string) (*Authorization, error) {
return &Authorization{ID: id, Status: StatusValid}, nil
},
}}, "", false},
{"ok fingerprint", fields{[]string{"az1", "az2"}}, args{ctx, &MockDB{
MockGetAuthorization: func(ctx context.Context, id string) (*Authorization, error) {
if id == "az1" {
return &Authorization{ID: id, Status: StatusValid}, nil
}
return &Authorization{ID: id, Fingerprint: "fingerprint", Status: StatusValid}, nil
},
}}, "fingerprint", false},
{"fail", fields{[]string{"az1", "az2"}}, args{ctx, &MockDB{
MockGetAuthorization: func(ctx context.Context, id string) (*Authorization, error) {
return nil, errors.New("force")
},
}}, "", true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
o := &Order{
AuthorizationIDs: tt.fields.AuthorizationIDs,
}
got, err := o.getAuthorizationFingerprint(tt.args.ctx, tt.args.db)
if (err != nil) != tt.wantErr {
t.Errorf("Order.getAuthorizationFingerprint() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("Order.getAuthorizationFingerprint() = %v, want %v", got, tt.want)
}
})
}
}

@ -1,6 +1,7 @@
package api
import (
"bytes"
"context"
"crypto"
"crypto/dsa" //nolint:staticcheck // support legacy algorithms
@ -18,10 +19,13 @@ import (
"strings"
"time"
"github.com/go-chi/chi"
"github.com/go-chi/chi/v5"
"github.com/pkg/errors"
"go.step.sm/crypto/sshutil"
"golang.org/x/crypto/ssh"
"github.com/smallstep/certificates/api/log"
"github.com/smallstep/certificates/api/models"
"github.com/smallstep/certificates/api/render"
"github.com/smallstep/certificates/authority"
"github.com/smallstep/certificates/authority/config"
@ -38,8 +42,9 @@ type Authority interface {
AuthorizeRenewToken(ctx context.Context, ott string) (*x509.Certificate, error)
GetTLSOptions() *config.TLSOptions
Root(shasum string) (*x509.Certificate, error)
Sign(cr *x509.CertificateRequest, opts provisioner.SignOptions, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error)
SignWithContext(ctx context.Context, cr *x509.CertificateRequest, opts provisioner.SignOptions, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error)
Renew(peer *x509.Certificate) ([]*x509.Certificate, error)
RenewContext(ctx context.Context, peer *x509.Certificate, pk crypto.PublicKey) ([]*x509.Certificate, error)
Rekey(peer *x509.Certificate, pk crypto.PublicKey) ([]*x509.Certificate, error)
LoadProvisionerByCertificate(*x509.Certificate) (provisioner.Interface, error)
LoadProvisionerByName(string) (provisioner.Interface, error)
@ -49,6 +54,7 @@ type Authority interface {
GetRoots() ([]*x509.Certificate, error)
GetFederation() ([]*x509.Certificate, error)
Version() authority.Version
GetCertificateRevocationList() (*authority.CertificateRevocationListInfo, error)
}
// mustAuthority will be replaced on unit tests.
@ -222,8 +228,60 @@ type RootResponse struct {
// ProvisionersResponse is the response object that returns the list of
// provisioners.
type ProvisionersResponse struct {
Provisioners provisioner.List `json:"provisioners"`
NextCursor string `json:"nextCursor"`
Provisioners provisioner.List
NextCursor string
}
const redacted = "*** REDACTED ***"
func scepFromProvisioner(p *provisioner.SCEP) *models.SCEP {
return &models.SCEP{
ID: p.ID,
Type: p.Type,
Name: p.Name,
ForceCN: p.ForceCN,
ChallengePassword: redacted,
Capabilities: p.Capabilities,
IncludeRoot: p.IncludeRoot,
ExcludeIntermediate: p.ExcludeIntermediate,
MinimumPublicKeyLength: p.MinimumPublicKeyLength,
DecrypterCertificate: []byte(redacted),
DecrypterKeyPEM: []byte(redacted),
DecrypterKeyURI: redacted,
DecrypterKeyPassword: redacted,
EncryptionAlgorithmIdentifier: p.EncryptionAlgorithmIdentifier,
Options: p.Options,
Claims: p.Claims,
}
}
// MarshalJSON implements json.Marshaler. It marshals the ProvisionersResponse
// into a byte slice.
//
// Special treatment is given to the SCEP provisioner, as it contains a
// challenge secret that MUST NOT be leaked in (public) HTTP responses. The
// challenge value is thus redacted in HTTP responses.
func (p ProvisionersResponse) MarshalJSON() ([]byte, error) {
var responseProvisioners provisioner.List
for _, item := range p.Provisioners {
scepProv, ok := item.(*provisioner.SCEP)
if !ok {
responseProvisioners = append(responseProvisioners, item)
continue
}
responseProvisioners = append(responseProvisioners, scepFromProvisioner(scepProv))
}
var list = struct {
Provisioners []provisioner.Interface `json:"provisioners"`
NextCursor string `json:"nextCursor"`
}{
Provisioners: []provisioner.Interface(responseProvisioners),
NextCursor: p.NextCursor,
}
return json.Marshal(list)
}
// ProvisionerKeyResponse is the response object that returns the encrypted key
@ -255,7 +313,7 @@ func (h *caHandler) Route(r Router) {
// New creates a new RouterHandler with the CA endpoints.
//
// Deprecated: Use api.Route(r Router)
func New(auth Authority) RouterHandler {
func New(Authority) RouterHandler {
return &caHandler{}
}
@ -267,6 +325,7 @@ func Route(r Router) {
r.MethodFunc("POST", "/renew", Renew)
r.MethodFunc("POST", "/rekey", Rekey)
r.MethodFunc("POST", "/revoke", Revoke)
r.MethodFunc("GET", "/crl", CRL)
r.MethodFunc("GET", "/provisioners", Provisioners)
r.MethodFunc("GET", "/provisioners/{kid}/encrypted-key", ProvisionerKey)
r.MethodFunc("GET", "/roots", Roots)
@ -294,7 +353,7 @@ func Route(r Router) {
// Version is an HTTP handler that returns the version of the server.
func Version(w http.ResponseWriter, r *http.Request) {
v := mustAuthority(r.Context()).Version()
render.JSON(w, VersionResponse{
render.JSON(w, r, VersionResponse{
Version: v.Version,
RequireClientAuthentication: v.RequireClientAuthentication,
})
@ -302,7 +361,7 @@ func Version(w http.ResponseWriter, r *http.Request) {
// Health is an HTTP handler that returns the status of the server.
func Health(w http.ResponseWriter, r *http.Request) {
render.JSON(w, HealthResponse{Status: "ok"})
render.JSON(w, r, HealthResponse{Status: "ok"})
}
// Root is an HTTP handler that using the SHA256 from the URL, returns the root
@ -313,11 +372,11 @@ func Root(w http.ResponseWriter, r *http.Request) {
// Load root certificate with the
cert, err := mustAuthority(r.Context()).Root(sum)
if err != nil {
render.Error(w, errs.Wrapf(http.StatusNotFound, err, "%s was not found", r.RequestURI))
render.Error(w, r, errs.Wrapf(http.StatusNotFound, err, "%s was not found", r.RequestURI))
return
}
render.JSON(w, &RootResponse{RootPEM: Certificate{cert}})
render.JSON(w, r, &RootResponse{RootPEM: Certificate{cert}})
}
func certChainToPEM(certChain []*x509.Certificate) []Certificate {
@ -332,17 +391,17 @@ func certChainToPEM(certChain []*x509.Certificate) []Certificate {
func Provisioners(w http.ResponseWriter, r *http.Request) {
cursor, limit, err := ParseCursor(r)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
p, next, err := mustAuthority(r.Context()).GetProvisioners(cursor, limit)
if err != nil {
render.Error(w, errs.InternalServerErr(err))
render.Error(w, r, errs.InternalServerErr(err))
return
}
render.JSON(w, &ProvisionersResponse{
render.JSON(w, r, &ProvisionersResponse{
Provisioners: p,
NextCursor: next,
})
@ -353,18 +412,18 @@ func ProvisionerKey(w http.ResponseWriter, r *http.Request) {
kid := chi.URLParam(r, "kid")
key, err := mustAuthority(r.Context()).GetEncryptedKey(kid)
if err != nil {
render.Error(w, errs.NotFoundErr(err))
render.Error(w, r, errs.NotFoundErr(err))
return
}
render.JSON(w, &ProvisionerKeyResponse{key})
render.JSON(w, r, &ProvisionerKeyResponse{key})
}
// Roots returns all the root certificates for the CA.
func Roots(w http.ResponseWriter, r *http.Request) {
roots, err := mustAuthority(r.Context()).GetRoots()
if err != nil {
render.Error(w, errs.ForbiddenErr(err, "error getting roots"))
render.Error(w, r, errs.ForbiddenErr(err, "error getting roots"))
return
}
@ -373,7 +432,7 @@ func Roots(w http.ResponseWriter, r *http.Request) {
certs[i] = Certificate{roots[i]}
}
render.JSONStatus(w, &RootsResponse{
render.JSONStatus(w, r, &RootsResponse{
Certificates: certs,
}, http.StatusCreated)
}
@ -382,7 +441,7 @@ func Roots(w http.ResponseWriter, r *http.Request) {
func RootsPEM(w http.ResponseWriter, r *http.Request) {
roots, err := mustAuthority(r.Context()).GetRoots()
if err != nil {
render.Error(w, errs.InternalServerErr(err))
render.Error(w, r, errs.InternalServerErr(err))
return
}
@ -395,7 +454,7 @@ func RootsPEM(w http.ResponseWriter, r *http.Request) {
})
if _, err := w.Write(block); err != nil {
log.Error(w, err)
log.Error(w, r, err)
return
}
}
@ -405,7 +464,7 @@ func RootsPEM(w http.ResponseWriter, r *http.Request) {
func Federation(w http.ResponseWriter, r *http.Request) {
federated, err := mustAuthority(r.Context()).GetFederation()
if err != nil {
render.Error(w, errs.ForbiddenErr(err, "error getting federated roots"))
render.Error(w, r, errs.ForbiddenErr(err, "error getting federated roots"))
return
}
@ -414,7 +473,7 @@ func Federation(w http.ResponseWriter, r *http.Request) {
certs[i] = Certificate{federated[i]}
}
render.JSONStatus(w, &FederationResponse{
render.JSONStatus(w, r, &FederationResponse{
Certificates: certs,
}, http.StatusCreated)
}
@ -435,7 +494,7 @@ func logOtt(w http.ResponseWriter, token string) {
}
}
// LogCertificate add certificate fields to the log message.
// LogCertificate adds certificate fields to the log message.
func LogCertificate(w http.ResponseWriter, cert *x509.Certificate) {
if rl, ok := w.(logging.ResponseLogger); ok {
m := map[string]interface{}{
@ -467,11 +526,46 @@ func LogCertificate(w http.ResponseWriter, cert *x509.Certificate) {
}
}
// LogSSHCertificate adds SSH certificate fields to the log message.
func LogSSHCertificate(w http.ResponseWriter, cert *ssh.Certificate) {
if rl, ok := w.(logging.ResponseLogger); ok {
mak := bytes.TrimSpace(ssh.MarshalAuthorizedKey(cert))
var certificate string
parts := strings.Split(string(mak), " ")
if len(parts) > 1 {
certificate = parts[1]
}
var userOrHost string
if cert.CertType == ssh.HostCert {
userOrHost = "host"
} else {
userOrHost = "user"
}
certificateType := fmt.Sprintf("%s %s certificate", parts[0], userOrHost) // e.g. ecdsa-sha2-nistp256-cert-v01@openssh.com user certificate
m := map[string]interface{}{
"serial": cert.Serial,
"principals": cert.ValidPrincipals,
"valid-from": time.Unix(int64(cert.ValidAfter), 0).Format(time.RFC3339),
"valid-to": time.Unix(int64(cert.ValidBefore), 0).Format(time.RFC3339),
"certificate": certificate,
"certificate-type": certificateType,
}
fingerprint, err := sshutil.FormatFingerprint(mak, sshutil.DefaultFingerprint)
if err == nil {
fpParts := strings.Split(fingerprint, " ")
if len(fpParts) > 3 {
m["public-key"] = fmt.Sprintf("%s %s", fpParts[1], fpParts[len(fpParts)-1])
}
}
rl.WithFields(m)
}
}
// ParseCursor parses the cursor and limit from the request query params.
func ParseCursor(r *http.Request) (cursor string, limit int, err error) {
q := r.URL.Query()
cursor = q.Get("cursor")
if v := q.Get("limit"); len(v) > 0 {
if v := q.Get("limit"); v != "" {
limit, err = strconv.Atoi(v)
if err != nil {
return "", 0, errs.BadRequestErr(err, "limit '%s' is not an integer", v)

@ -4,7 +4,7 @@ import (
"bytes"
"context"
"crypto"
"crypto/dsa" //nolint
"crypto/dsa" //nolint:staticcheck // support legacy algorithms
"crypto/ecdsa"
"crypto/ed25519"
"crypto/elliptic"
@ -26,14 +26,14 @@ import (
"testing"
"time"
"github.com/go-chi/chi"
"github.com/go-chi/chi/v5"
"github.com/pkg/errors"
"golang.org/x/crypto/ssh"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.step.sm/crypto/jose"
"go.step.sm/crypto/x509util"
"golang.org/x/crypto/ssh"
"github.com/smallstep/assert"
"github.com/smallstep/certificates/authority"
"github.com/smallstep/certificates/authority/provisioner"
"github.com/smallstep/certificates/errs"
@ -189,9 +189,10 @@ type mockAuthority struct {
authorizeRenewToken func(ctx context.Context, ott string) (*x509.Certificate, error)
getTLSOptions func() *authority.TLSOptions
root func(shasum string) (*x509.Certificate, error)
sign func(cr *x509.CertificateRequest, opts provisioner.SignOptions, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error)
signWithContext func(ctx context.Context, cr *x509.CertificateRequest, opts provisioner.SignOptions, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error)
renew func(cert *x509.Certificate) ([]*x509.Certificate, error)
rekey func(oldCert *x509.Certificate, pk crypto.PublicKey) ([]*x509.Certificate, error)
renewContext func(ctx context.Context, oldCert *x509.Certificate, pk crypto.PublicKey) ([]*x509.Certificate, error)
loadProvisionerByCertificate func(cert *x509.Certificate) (provisioner.Interface, error)
loadProvisionerByName func(name string) (provisioner.Interface, error)
getProvisioners func(nextCursor string, limit int) (provisioner.List, string, error)
@ -199,6 +200,7 @@ type mockAuthority struct {
getEncryptedKey func(kid string) (string, error)
getRoots func() ([]*x509.Certificate, error)
getFederation func() ([]*x509.Certificate, error)
getCRL func() (*authority.CertificateRevocationListInfo, error)
signSSH func(ctx context.Context, key ssh.PublicKey, opts provisioner.SignSSHOptions, signOpts ...provisioner.SignOption) (*ssh.Certificate, error)
signSSHAddUser func(ctx context.Context, key ssh.PublicKey, cert *ssh.Certificate) (*ssh.Certificate, error)
renewSSH func(ctx context.Context, cert *ssh.Certificate) (*ssh.Certificate, error)
@ -212,6 +214,14 @@ type mockAuthority struct {
version func() authority.Version
}
func (m *mockAuthority) GetCertificateRevocationList() (*authority.CertificateRevocationListInfo, error) {
if m.getCRL != nil {
return m.getCRL()
}
return m.ret1.(*authority.CertificateRevocationListInfo), m.err
}
// TODO: remove once Authorize is deprecated.
func (m *mockAuthority) Authorize(ctx context.Context, ott string) ([]provisioner.SignOption, error) {
if m.authorize != nil {
@ -241,9 +251,9 @@ func (m *mockAuthority) Root(shasum string) (*x509.Certificate, error) {
return m.ret1.(*x509.Certificate), m.err
}
func (m *mockAuthority) Sign(cr *x509.CertificateRequest, opts provisioner.SignOptions, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
if m.sign != nil {
return m.sign(cr, opts, signOpts...)
func (m *mockAuthority) SignWithContext(ctx context.Context, cr *x509.CertificateRequest, opts provisioner.SignOptions, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
if m.signWithContext != nil {
return m.signWithContext(ctx, cr, opts, signOpts...)
}
return []*x509.Certificate{m.ret1.(*x509.Certificate), m.ret2.(*x509.Certificate)}, m.err
}
@ -255,6 +265,13 @@ func (m *mockAuthority) Renew(cert *x509.Certificate) ([]*x509.Certificate, erro
return []*x509.Certificate{m.ret1.(*x509.Certificate), m.ret2.(*x509.Certificate)}, m.err
}
func (m *mockAuthority) RenewContext(ctx context.Context, oldcert *x509.Certificate, pk crypto.PublicKey) ([]*x509.Certificate, error) {
if m.renewContext != nil {
return m.renewContext(ctx, oldcert, pk)
}
return []*x509.Certificate{m.ret1.(*x509.Certificate), m.ret2.(*x509.Certificate)}, m.err
}
func (m *mockAuthority) Rekey(oldcert *x509.Certificate, pk crypto.PublicKey) ([]*x509.Certificate, error) {
if m.rekey != nil {
return m.rekey(oldcert, pk)
@ -638,7 +655,7 @@ func TestSignRequest_Validate(t *testing.T) {
}
if err := s.Validate(); err != nil {
if assert.NotNil(t, tt.err) {
assert.HasPrefix(t, err.Error(), tt.err.Error())
assert.True(t, strings.HasPrefix(err.Error(), tt.err.Error()))
}
} else {
assert.Nil(t, tt.err)
@ -797,7 +814,7 @@ func Test_caHandler_Route(t *testing.T) {
}
func Test_Health(t *testing.T) {
req := httptest.NewRequest("GET", "http://example.com/health", nil)
req := httptest.NewRequest("GET", "http://example.com/health", http.NoBody)
w := httptest.NewRecorder()
Health(w, req)
@ -831,7 +848,7 @@ func Test_Root(t *testing.T) {
// Request with chi context
chiCtx := chi.NewRouteContext()
chiCtx.URLParams.Add("sha", "efc7d6b475a56fe587650bcdb999a4a308f815ba44db4bf0371ea68a786ccd36")
req := httptest.NewRequest("GET", "http://example.com/root/efc7d6b475a56fe587650bcdb999a4a308f815ba44db4bf0371ea68a786ccd36", nil)
req := httptest.NewRequest("GET", "http://example.com/root/efc7d6b475a56fe587650bcdb999a4a308f815ba44db4bf0371ea68a786ccd36", http.NoBody)
req = req.WithContext(context.WithValue(context.Background(), chi.RouteCtxKey, chiCtx))
expected := []byte(`{"ca":"` + strings.ReplaceAll(rootPEM, "\n", `\n`) + `\n"}`)
@ -867,16 +884,12 @@ func Test_Sign(t *testing.T) {
CsrPEM: CertificateRequest{csr},
OTT: "foobarzar",
})
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
invalid, err := json.Marshal(SignRequest{
CsrPEM: CertificateRequest{csr},
OTT: "",
})
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
expected1 := []byte(`{"crt":"` + strings.ReplaceAll(certPEM, "\n", `\n`) + `\n","ca":"` + strings.ReplaceAll(rootPEM, "\n", `\n`) + `\n","certChain":["` + strings.ReplaceAll(certPEM, "\n", `\n`) + `\n","` + strings.ReplaceAll(rootPEM, "\n", `\n`) + `\n"]}`)
expected2 := []byte(`{"crt":"` + strings.ReplaceAll(stepCertPEM, "\n", `\n`) + `\n","ca":"` + strings.ReplaceAll(rootPEM, "\n", `\n`) + `\n","certChain":["` + strings.ReplaceAll(stepCertPEM, "\n", `\n`) + `\n","` + strings.ReplaceAll(rootPEM, "\n", `\n`) + `\n"]}`)
@ -1046,7 +1059,7 @@ func Test_Renew(t *testing.T) {
return nil
},
})
req := httptest.NewRequest("POST", "http://example.com/renew", nil)
req := httptest.NewRequest("POST", "http://example.com/renew", http.NoBody)
req.TLS = tt.tls
req.Header = tt.header
w := httptest.NewRecorder()
@ -1200,10 +1213,10 @@ func Test_Provisioners(t *testing.T) {
expectedError400 := errs.BadRequest("limit 'abc' is not an integer")
expectedError400Bytes, err := json.Marshal(expectedError400)
assert.FatalError(t, err)
require.NoError(t, err)
expectedError500 := errs.InternalServer("force")
expectedError500Bytes, err := json.Marshal(expectedError500)
assert.FatalError(t, err)
require.NoError(t, err)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
mockMustAuthority(t, tt.fields.Authority)
@ -1254,7 +1267,7 @@ func Test_ProvisionerKey(t *testing.T) {
// Request with chi context
chiCtx := chi.NewRouteContext()
chiCtx.URLParams.Add("kid", "oV1p0MJeGQ7qBlK6B-oyfVdBRjh_e7VSK_YSEEqgW00")
req := httptest.NewRequest("GET", "http://example.com/provisioners/oV1p0MJeGQ7qBlK6B-oyfVdBRjh_e7VSK_YSEEqgW00/encrypted-key", nil)
req := httptest.NewRequest("GET", "http://example.com/provisioners/oV1p0MJeGQ7qBlK6B-oyfVdBRjh_e7VSK_YSEEqgW00/encrypted-key", http.NoBody)
req = req.WithContext(context.WithValue(context.Background(), chi.RouteCtxKey, chiCtx))
tests := []struct {
@ -1270,7 +1283,7 @@ func Test_ProvisionerKey(t *testing.T) {
expected := []byte(`{"key":"` + privKey + `"}`)
expectedError404 := errs.NotFound("force")
expectedError404Bytes, err := json.Marshal(expectedError404)
assert.FatalError(t, err)
require.NoError(t, err)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@ -1322,7 +1335,7 @@ func Test_Roots(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
mockMustAuthority(t, &mockAuthority{ret1: []*x509.Certificate{tt.root}, err: tt.err})
req := httptest.NewRequest("GET", "http://example.com/roots", nil)
req := httptest.NewRequest("GET", "http://example.com/roots", http.NoBody)
req.TLS = tt.tls
w := httptest.NewRecorder()
Roots(w, req)
@ -1363,7 +1376,7 @@ func Test_caHandler_RootsPEM(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
mockMustAuthority(t, &mockAuthority{ret1: tt.roots, err: tt.err})
req := httptest.NewRequest("GET", "https://example.com/roots", nil)
req := httptest.NewRequest("GET", "https://example.com/roots", http.NoBody)
w := httptest.NewRecorder()
RootsPEM(w, req)
res := w.Result()
@ -1408,7 +1421,7 @@ func Test_Federation(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
mockMustAuthority(t, &mockAuthority{ret1: []*x509.Certificate{tt.root}, err: tt.err})
req := httptest.NewRequest("GET", "http://example.com/federation", nil)
req := httptest.NewRequest("GET", "http://example.com/federation", http.NoBody)
req.TLS = tt.tls
w := httptest.NewRecorder()
Federation(w, req)
@ -1508,3 +1521,140 @@ func mustCertificate(t *testing.T, pub, priv interface{}) *x509.Certificate {
}
return cert
}
func TestProvisionersResponse_MarshalJSON(t *testing.T) {
k := map[string]any{
"use": "sig",
"kty": "EC",
"kid": "4UELJx8e0aS9m0CH3fZ0EB7D5aUPICb759zALHFejvc",
"crv": "P-256",
"alg": "ES256",
"x": "7ZdAAMZCFU4XwgblI5RfZouBi8lYmF6DlZusNNnsbm8",
"y": "sQr2JdzwD2fgyrymBEXWsxDxFNjjqN64qLLSbLdLZ9Y",
}
key := jose.JSONWebKey{}
b, err := json.Marshal(k)
require.NoError(t, err)
err = json.Unmarshal(b, &key)
require.NoError(t, err)
r := ProvisionersResponse{
Provisioners: provisioner.List{
&provisioner.SCEP{
Name: "scep",
Type: "scep",
ChallengePassword: "not-so-secret",
MinimumPublicKeyLength: 2048,
EncryptionAlgorithmIdentifier: 2,
IncludeRoot: true,
ExcludeIntermediate: true,
DecrypterCertificate: []byte{1, 2, 3, 4},
DecrypterKeyPEM: []byte{5, 6, 7, 8},
DecrypterKeyURI: "softkms:path=/path/to/private.key",
DecrypterKeyPassword: "super-secret-password",
},
&provisioner.JWK{
EncryptedKey: "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4R0NNIiwicDJjIjoxMDAwMDAsInAycyI6IlhOdmYxQjgxSUlLMFA2NUkwcmtGTGcifQ.XaN9zcPQeWt49zchUDm34FECUTHfQTn_.tmNHPQDqR3ebsWfd.9WZr3YVdeOyJh36vvx0VlRtluhvYp4K7jJ1KGDr1qypwZ3ziBVSNbYYQ71du7fTtrnfG1wgGTVR39tWSzBU-zwQ5hdV3rpMAaEbod5zeW6SHd95H3Bvcb43YiiqJFNL5sGZzFb7FqzVmpsZ1efiv6sZaGDHtnCAL6r12UG5EZuqGfM0jGCZitUz2m9TUKXJL5DJ7MOYbFfkCEsUBPDm_TInliSVn2kMJhFa0VOe5wZk5YOuYM3lNYW64HGtbf-llN2Xk-4O9TfeSPizBx9ZqGpeu8pz13efUDT2WL9tWo6-0UE-CrG0bScm8lFTncTkHcu49_a5NaUBkYlBjEiw.thPcx3t1AUcWuEygXIY3Fg",
Key: &key,
Name: "step-cli",
Type: "JWK",
},
},
NextCursor: "next",
}
expected := map[string]any{
"provisioners": []map[string]any{
{
"type": "scep",
"name": "scep",
"forceCN": false,
"includeRoot": true,
"excludeIntermediate": true,
"challenge": "*** REDACTED ***",
"decrypterCertificate": []byte("*** REDACTED ***"),
"decrypterKey": "*** REDACTED ***",
"decrypterKeyPEM": []byte("*** REDACTED ***"),
"decrypterKeyPassword": "*** REDACTED ***",
"minimumPublicKeyLength": 2048,
"encryptionAlgorithmIdentifier": 2,
},
{
"type": "JWK",
"name": "step-cli",
"key": map[string]any{
"use": "sig",
"kty": "EC",
"kid": "4UELJx8e0aS9m0CH3fZ0EB7D5aUPICb759zALHFejvc",
"crv": "P-256",
"alg": "ES256",
"x": "7ZdAAMZCFU4XwgblI5RfZouBi8lYmF6DlZusNNnsbm8",
"y": "sQr2JdzwD2fgyrymBEXWsxDxFNjjqN64qLLSbLdLZ9Y",
},
"encryptedKey": "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4R0NNIiwicDJjIjoxMDAwMDAsInAycyI6IlhOdmYxQjgxSUlLMFA2NUkwcmtGTGcifQ.XaN9zcPQeWt49zchUDm34FECUTHfQTn_.tmNHPQDqR3ebsWfd.9WZr3YVdeOyJh36vvx0VlRtluhvYp4K7jJ1KGDr1qypwZ3ziBVSNbYYQ71du7fTtrnfG1wgGTVR39tWSzBU-zwQ5hdV3rpMAaEbod5zeW6SHd95H3Bvcb43YiiqJFNL5sGZzFb7FqzVmpsZ1efiv6sZaGDHtnCAL6r12UG5EZuqGfM0jGCZitUz2m9TUKXJL5DJ7MOYbFfkCEsUBPDm_TInliSVn2kMJhFa0VOe5wZk5YOuYM3lNYW64HGtbf-llN2Xk-4O9TfeSPizBx9ZqGpeu8pz13efUDT2WL9tWo6-0UE-CrG0bScm8lFTncTkHcu49_a5NaUBkYlBjEiw.thPcx3t1AUcWuEygXIY3Fg",
},
},
"nextCursor": "next",
}
expBytes, err := json.Marshal(expected)
assert.NoError(t, err)
br, err := r.MarshalJSON()
assert.NoError(t, err)
assert.JSONEq(t, string(expBytes), string(br))
keyCopy := key
expList := provisioner.List{
&provisioner.SCEP{
Name: "scep",
Type: "scep",
ChallengePassword: "not-so-secret",
MinimumPublicKeyLength: 2048,
EncryptionAlgorithmIdentifier: 2,
IncludeRoot: true,
ExcludeIntermediate: true,
DecrypterCertificate: []byte{1, 2, 3, 4},
DecrypterKeyPEM: []byte{5, 6, 7, 8},
DecrypterKeyURI: "softkms:path=/path/to/private.key",
DecrypterKeyPassword: "super-secret-password",
},
&provisioner.JWK{
EncryptedKey: "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4R0NNIiwicDJjIjoxMDAwMDAsInAycyI6IlhOdmYxQjgxSUlLMFA2NUkwcmtGTGcifQ.XaN9zcPQeWt49zchUDm34FECUTHfQTn_.tmNHPQDqR3ebsWfd.9WZr3YVdeOyJh36vvx0VlRtluhvYp4K7jJ1KGDr1qypwZ3ziBVSNbYYQ71du7fTtrnfG1wgGTVR39tWSzBU-zwQ5hdV3rpMAaEbod5zeW6SHd95H3Bvcb43YiiqJFNL5sGZzFb7FqzVmpsZ1efiv6sZaGDHtnCAL6r12UG5EZuqGfM0jGCZitUz2m9TUKXJL5DJ7MOYbFfkCEsUBPDm_TInliSVn2kMJhFa0VOe5wZk5YOuYM3lNYW64HGtbf-llN2Xk-4O9TfeSPizBx9ZqGpeu8pz13efUDT2WL9tWo6-0UE-CrG0bScm8lFTncTkHcu49_a5NaUBkYlBjEiw.thPcx3t1AUcWuEygXIY3Fg",
Key: &keyCopy,
Name: "step-cli",
Type: "JWK",
},
}
// MarshalJSON must not affect the struct properties itself
assert.Equal(t, expList, r.Provisioners)
}
const (
fixtureECDSACertificate = `ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgLnkvSk4odlo3b1R+RDw+LmorL3RkN354IilCIVFVen4AAAAIbmlzdHAyNTYAAABBBHjKHss8WM2ffMYlavisoLXR0I6UEIU+cidV1ogEH1U6+/SYaFPrlzQo0tGLM5CNkMbhInbyasQsrHzn8F1Rt7nHg5/tcSf9qwAAAAEAAAAGaGVybWFuAAAACgAAAAZoZXJtYW4AAAAAY8kvJwAAAABjyhBjAAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAAGgAAAATZWNkc2Etc2hhMi1uaXN0cDI1NgAAAAhuaXN0cDI1NgAAAEEE/ayqpPrZZF5uA1UlDt4FreTf15agztQIzpxnWq/XoxAHzagRSkFGkdgFpjgsfiRpP8URHH3BZScqc0ZDCTxhoQAAAGQAAAATZWNkc2Etc2hhMi1uaXN0cDI1NgAAAEkAAAAhAJuP1wCVwoyrKrEtHGfFXrVbRHySDjvXtS1tVTdHyqymAAAAIBa/CSSzfZb4D2NLP+eEmOOMJwSjYOiNM8fiOoAaqglI herman`
)
func TestLogSSHCertificate(t *testing.T) {
out, _, _, _, err := ssh.ParseAuthorizedKey([]byte(fixtureECDSACertificate))
require.NoError(t, err)
cert, ok := out.(*ssh.Certificate)
require.True(t, ok)
w := httptest.NewRecorder()
rl := logging.NewResponseLogger(w)
LogSSHCertificate(rl, cert)
assert.Equal(t, 200, w.Result().StatusCode)
fields := rl.Fields()
assert.Equal(t, uint64(14376510277651266987), fields["serial"])
assert.Equal(t, []string{"herman"}, fields["principals"])
assert.Equal(t, "ecdsa-sha2-nistp256-cert-v01@openssh.com user certificate", fields["certificate-type"])
assert.Equal(t, time.Unix(1674129191, 0).Format(time.RFC3339), fields["valid-from"])
assert.Equal(t, time.Unix(1674186851, 0).Format(time.RFC3339), fields["valid-to"])
assert.Equal(t, "AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgLnkvSk4odlo3b1R+RDw+LmorL3RkN354IilCIVFVen4AAAAIbmlzdHAyNTYAAABBBHjKHss8WM2ffMYlavisoLXR0I6UEIU+cidV1ogEH1U6+/SYaFPrlzQo0tGLM5CNkMbhInbyasQsrHzn8F1Rt7nHg5/tcSf9qwAAAAEAAAAGaGVybWFuAAAACgAAAAZoZXJtYW4AAAAAY8kvJwAAAABjyhBjAAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAAGgAAAATZWNkc2Etc2hhMi1uaXN0cDI1NgAAAAhuaXN0cDI1NgAAAEEE/ayqpPrZZF5uA1UlDt4FreTf15agztQIzpxnWq/XoxAHzagRSkFGkdgFpjgsfiRpP8URHH3BZScqc0ZDCTxhoQAAAGQAAAATZWNkc2Etc2hhMi1uaXN0cDI1NgAAAEkAAAAhAJuP1wCVwoyrKrEtHGfFXrVbRHySDjvXtS1tVTdHyqymAAAAIBa/CSSzfZb4D2NLP+eEmOOMJwSjYOiNM8fiOoAaqglI", fields["certificate"])
assert.Equal(t, "SHA256:RvkDPGwl/G9d7LUFm1kmWhvOD9I/moPq4yxcb0STwr0 (ECDSA-CERT)", fields["public-key"])
}

@ -0,0 +1,46 @@
package api
import (
"encoding/pem"
"net/http"
"time"
"github.com/smallstep/certificates/api/render"
"github.com/smallstep/certificates/errs"
)
// CRL is an HTTP handler that returns the current CRL in DER or PEM format
func CRL(w http.ResponseWriter, r *http.Request) {
crlInfo, err := mustAuthority(r.Context()).GetCertificateRevocationList()
if err != nil {
render.Error(w, r, err)
return
}
if crlInfo == nil {
render.Error(w, r, errs.New(http.StatusNotFound, "no CRL available"))
return
}
expires := crlInfo.ExpiresAt
if expires.IsZero() {
expires = time.Now()
}
w.Header().Add("Expires", expires.Format(time.RFC1123))
_, formatAsPEM := r.URL.Query()["pem"]
if formatAsPEM {
w.Header().Add("Content-Type", "application/x-pem-file")
w.Header().Add("Content-Disposition", "attachment; filename=\"crl.pem\"")
_ = pem.Encode(w, &pem.Block{
Type: "X509 CRL",
Bytes: crlInfo.Data,
})
} else {
w.Header().Add("Content-Type", "application/pkix-crl")
w.Header().Add("Content-Disposition", "attachment; filename=\"crl.der\"")
w.Write(crlInfo.Data)
}
}

@ -0,0 +1,93 @@
package api
import (
"bytes"
"context"
"encoding/pem"
"io"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/go-chi/chi/v5"
"github.com/pkg/errors"
"github.com/smallstep/certificates/authority"
"github.com/smallstep/certificates/errs"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func Test_CRL(t *testing.T) {
data := []byte{1, 2, 3, 4}
pemData := pem.EncodeToMemory(&pem.Block{
Type: "X509 CRL",
Bytes: data,
})
pemData = bytes.TrimSpace(pemData)
emptyPEMData := pem.EncodeToMemory(&pem.Block{
Type: "X509 CRL",
Bytes: nil,
})
emptyPEMData = bytes.TrimSpace(emptyPEMData)
tests := []struct {
name string
url string
err error
statusCode int
crlInfo *authority.CertificateRevocationListInfo
expectedBody []byte
expectedHeaders http.Header
expectedErrorJSON string
}{
{"ok", "http://example.com/crl", nil, http.StatusOK, &authority.CertificateRevocationListInfo{Data: data}, data, http.Header{"Content-Type": []string{"application/pkix-crl"}, "Content-Disposition": []string{`attachment; filename="crl.der"`}}, ""},
{"ok/pem", "http://example.com/crl?pem=true", nil, http.StatusOK, &authority.CertificateRevocationListInfo{Data: data}, pemData, http.Header{"Content-Type": []string{"application/x-pem-file"}, "Content-Disposition": []string{`attachment; filename="crl.pem"`}}, ""},
{"ok/empty", "http://example.com/crl", nil, http.StatusOK, &authority.CertificateRevocationListInfo{Data: nil}, nil, http.Header{"Content-Type": []string{"application/pkix-crl"}, "Content-Disposition": []string{`attachment; filename="crl.der"`}}, ""},
{"ok/empty-pem", "http://example.com/crl?pem=true", nil, http.StatusOK, &authority.CertificateRevocationListInfo{Data: nil}, emptyPEMData, http.Header{"Content-Type": []string{"application/x-pem-file"}, "Content-Disposition": []string{`attachment; filename="crl.pem"`}}, ""},
{"fail/internal", "http://example.com/crl", errs.Wrap(http.StatusInternalServerError, errors.New("failure"), "authority.GetCertificateRevocationList"), http.StatusInternalServerError, nil, nil, http.Header{}, `{"status":500,"message":"The certificate authority encountered an Internal Server Error. Please see the certificate authority logs for more info."}`},
{"fail/nil", "http://example.com/crl", nil, http.StatusNotFound, nil, nil, http.Header{}, `{"status":404,"message":"no CRL available"}`},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
mockMustAuthority(t, &mockAuthority{ret1: tt.crlInfo, err: tt.err})
chiCtx := chi.NewRouteContext()
req := httptest.NewRequest("GET", tt.url, http.NoBody)
req = req.WithContext(context.WithValue(context.Background(), chi.RouteCtxKey, chiCtx))
w := httptest.NewRecorder()
CRL(w, req)
res := w.Result()
assert.Equal(t, tt.statusCode, res.StatusCode)
body, err := io.ReadAll(res.Body)
res.Body.Close()
require.NoError(t, err)
if tt.statusCode >= 300 {
assert.JSONEq(t, tt.expectedErrorJSON, string(bytes.TrimSpace(body)))
return
}
// check expected header values
for _, h := range []string{"content-type", "content-disposition"} {
v := tt.expectedHeaders.Get(h)
require.NotEmpty(t, v)
actual := res.Header.Get(h)
assert.Equal(t, v, actual)
}
// check expires header value
assert.NotEmpty(t, res.Header.Get("expires"))
t1, err := time.Parse(time.RFC1123, res.Header.Get("expires"))
if assert.NoError(t, err) {
assert.False(t, t1.IsZero())
}
// check body contents
assert.Equal(t, tt.expectedBody, bytes.TrimSpace(body))
})
}
}

@ -2,15 +2,37 @@
package log
import (
"context"
"fmt"
"net/http"
"os"
"github.com/pkg/errors"
"github.com/smallstep/certificates/logging"
)
type errorLoggerKey struct{}
// ErrorLogger is the function type used to log errors.
type ErrorLogger func(http.ResponseWriter, *http.Request, error)
func (fn ErrorLogger) call(w http.ResponseWriter, r *http.Request, err error) {
if fn == nil {
return
}
fn(w, r, err)
}
// WithErrorLogger returns a new context with the given error logger.
func WithErrorLogger(ctx context.Context, fn ErrorLogger) context.Context {
return context.WithValue(ctx, errorLoggerKey{}, fn)
}
// ErrorLoggerFromContext returns an error logger from the context.
func ErrorLoggerFromContext(ctx context.Context) (fn ErrorLogger) {
fn, _ = ctx.Value(errorLoggerKey{}).(ErrorLogger)
return
}
// StackTracedError is the set of errors implementing the StackTrace function.
//
// Errors implementing this interface have their stack traces logged when passed
@ -21,16 +43,23 @@ type StackTracedError interface {
StackTrace() errors.StackTrace
}
type fieldCarrier interface {
WithFields(map[string]any)
Fields() map[string]any
}
// Error adds to the response writer the given error if it implements
// logging.ResponseLogger. If it does not implement it, then writes the error
// using the log package.
func Error(rw http.ResponseWriter, err error) {
rl, ok := rw.(logging.ResponseLogger)
func Error(w http.ResponseWriter, r *http.Request, err error) {
ErrorLoggerFromContext(r.Context()).call(w, r, err)
fc, ok := w.(fieldCarrier)
if !ok {
return
}
rl.WithFields(map[string]interface{}{
fc.WithFields(map[string]any{
"error": err,
})
@ -39,8 +68,8 @@ func Error(rw http.ResponseWriter, err error) {
}
var st StackTracedError
if !errors.As(err, &st) {
rl.WithFields(map[string]interface{}{
if errors.As(err, &st) {
fc.WithFields(map[string]any{
"stack-trace": fmt.Sprintf("%+v", st.StackTrace()),
})
}
@ -48,21 +77,21 @@ func Error(rw http.ResponseWriter, err error) {
// EnabledResponse log the response object if it implements the EnableLogger
// interface.
func EnabledResponse(rw http.ResponseWriter, v interface{}) {
func EnabledResponse(rw http.ResponseWriter, r *http.Request, v any) {
type enableLogger interface {
ToLog() (interface{}, error)
ToLog() (any, error)
}
if el, ok := v.(enableLogger); ok {
out, err := el.ToLog()
if err != nil {
Error(rw, err)
Error(rw, r, err)
return
}
if rl, ok := rw.(logging.ResponseLogger); ok {
rl.WithFields(map[string]interface{}{
if rl, ok := rw.(fieldCarrier); ok {
rl.WithFields(map[string]any{
"response": out,
})
}

@ -1,43 +1,108 @@
package log
import (
"errors"
"bytes"
"encoding/json"
"log/slog"
"net/http"
"net/http/httptest"
"reflect"
"testing"
"unsafe"
pkgerrors "github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/smallstep/certificates/logging"
)
func TestError(t *testing.T) {
theError := errors.New("the error")
type stackTracedError struct{}
type args struct {
rw http.ResponseWriter
err error
func (stackTracedError) Error() string {
return "a stacktraced error"
}
func (stackTracedError) StackTrace() pkgerrors.StackTrace {
f := struct{}{}
return pkgerrors.StackTrace{ // fake stacktrace
pkgerrors.Frame(unsafe.Pointer(&f)),
pkgerrors.Frame(unsafe.Pointer(&f)),
}
}
func TestError(t *testing.T) {
var buf bytes.Buffer
logger := slog.New(slog.NewJSONHandler(&buf, &slog.HandlerOptions{}))
req := httptest.NewRequest("GET", "/test", http.NoBody)
reqWithLogger := req.WithContext(WithErrorLogger(req.Context(), func(w http.ResponseWriter, r *http.Request, err error) {
if err != nil {
logger.ErrorContext(r.Context(), "request failed", slog.Any("error", err))
}
}))
tests := []struct {
name string
args args
withFields bool
name string
error
rw http.ResponseWriter
r *http.Request
isFieldCarrier bool
isSlogLogger bool
stepDebug bool
expectStackTrace bool
}{
{"normalLogger", args{httptest.NewRecorder(), theError}, false},
{"responseLogger", args{logging.NewResponseLogger(httptest.NewRecorder()), theError}, true},
{"noLogger", nil, nil, req, false, false, false, false},
{"noError", nil, logging.NewResponseLogger(httptest.NewRecorder()), req, true, false, false, false},
{"noErrorDebug", nil, logging.NewResponseLogger(httptest.NewRecorder()), req, true, false, true, false},
{"anError", assert.AnError, logging.NewResponseLogger(httptest.NewRecorder()), req, true, false, false, false},
{"anErrorDebug", assert.AnError, logging.NewResponseLogger(httptest.NewRecorder()), req, true, false, true, false},
{"stackTracedError", new(stackTracedError), logging.NewResponseLogger(httptest.NewRecorder()), req, true, false, true, true},
{"stackTracedErrorDebug", new(stackTracedError), logging.NewResponseLogger(httptest.NewRecorder()), req, true, false, true, true},
{"slogWithNoError", nil, logging.NewResponseLogger(httptest.NewRecorder()), reqWithLogger, true, true, false, false},
{"slogWithError", assert.AnError, logging.NewResponseLogger(httptest.NewRecorder()), reqWithLogger, true, true, false, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Error(tt.args.rw, tt.args.err)
if tt.withFields {
if rl, ok := tt.args.rw.(logging.ResponseLogger); ok {
fields := rl.Fields()
if !reflect.DeepEqual(fields["error"], theError) {
t.Errorf("ResponseLogger[\"error\"] = %s, wants %s", fields["error"], theError)
}
if tt.stepDebug {
t.Setenv("STEPDEBUG", "1")
} else {
t.Setenv("STEPDEBUG", "0")
}
Error(tt.rw, tt.r, tt.error)
// return early if test case doesn't use logger
if !tt.isFieldCarrier && !tt.isSlogLogger {
return
}
if tt.isFieldCarrier {
fields := tt.rw.(logging.ResponseLogger).Fields()
// expect the error field to be (not) set and to be the same error that was fed to Error
if tt.error == nil {
assert.Nil(t, fields["error"])
} else {
t.Error("ResponseWriter does not implement logging.ResponseLogger")
assert.Same(t, tt.error, fields["error"])
}
// check if stack-trace is set when expected
if _, hasStackTrace := fields["stack-trace"]; tt.expectStackTrace && !hasStackTrace {
t.Error(`ResponseLogger["stack-trace"] not set`)
} else if !tt.expectStackTrace && hasStackTrace {
t.Error(`ResponseLogger["stack-trace"] was set`)
}
}
if tt.isSlogLogger {
b := buf.Bytes()
if tt.error == nil {
assert.Empty(t, b)
} else if assert.NotEmpty(t, b) {
var m map[string]any
assert.NoError(t, json.Unmarshal(b, &m))
assert.Equal(t, tt.error.Error(), m["error"])
}
buf.Reset()
}
})
}

@ -0,0 +1,118 @@
package models
import (
"context"
"crypto/x509"
"errors"
"github.com/smallstep/certificates/authority/provisioner"
"golang.org/x/crypto/ssh"
)
var errDummyImplementation = errors.New("dummy implementation")
// SCEP is the SCEP provisioner model used solely in CA API
// responses. All methods for the [provisioner.Interface] interface
// are implemented, but return a dummy error.
// TODO(hs): remove reliance on the interface for the API responses
type SCEP struct {
ID string `json:"-"`
Type string `json:"type"`
Name string `json:"name"`
ForceCN bool `json:"forceCN"`
ChallengePassword string `json:"challenge"`
Capabilities []string `json:"capabilities,omitempty"`
IncludeRoot bool `json:"includeRoot"`
ExcludeIntermediate bool `json:"excludeIntermediate"`
MinimumPublicKeyLength int `json:"minimumPublicKeyLength"`
DecrypterCertificate []byte `json:"decrypterCertificate"`
DecrypterKeyPEM []byte `json:"decrypterKeyPEM"`
DecrypterKeyURI string `json:"decrypterKey"`
DecrypterKeyPassword string `json:"decrypterKeyPassword"`
EncryptionAlgorithmIdentifier int `json:"encryptionAlgorithmIdentifier"`
Options *provisioner.Options `json:"options,omitempty"`
Claims *provisioner.Claims `json:"claims,omitempty"`
}
// GetID returns the provisioner unique identifier.
func (s *SCEP) GetID() string {
if s.ID != "" {
return s.ID
}
return s.GetIDForToken()
}
// GetIDForToken returns an identifier that will be used to load the provisioner
// from a token.
func (s *SCEP) GetIDForToken() string {
return "scep/" + s.Name
}
// GetName returns the name of the provisioner.
func (s *SCEP) GetName() string {
return s.Name
}
// GetType returns the type of provisioner.
func (s *SCEP) GetType() provisioner.Type {
return provisioner.TypeSCEP
}
// GetEncryptedKey returns the base provisioner encrypted key if it's defined.
func (s *SCEP) GetEncryptedKey() (string, string, bool) {
return "", "", false
}
// GetTokenID returns the identifier of the token.
func (s *SCEP) GetTokenID(string) (string, error) {
return "", errDummyImplementation
}
// Init initializes and validates the fields of a SCEP type.
func (s *SCEP) Init(_ provisioner.Config) (err error) {
return errDummyImplementation
}
// AuthorizeSign returns an unimplemented error. Provisioners should overwrite
// this method if they will support authorizing tokens for signing x509 Certificates.
func (s *SCEP) AuthorizeSign(context.Context, string) ([]provisioner.SignOption, error) {
return nil, errDummyImplementation
}
// AuthorizeRevoke returns an unimplemented error. Provisioners should overwrite
// this method if they will support authorizing tokens for revoking x509 Certificates.
func (s *SCEP) AuthorizeRevoke(context.Context, string) error {
return errDummyImplementation
}
// AuthorizeRenew returns an unimplemented error. Provisioners should overwrite
// this method if they will support authorizing tokens for renewing x509 Certificates.
func (s *SCEP) AuthorizeRenew(context.Context, *x509.Certificate) error {
return errDummyImplementation
}
// AuthorizeSSHSign returns an unimplemented error. Provisioners should overwrite
// this method if they will support authorizing tokens for signing SSH Certificates.
func (s *SCEP) AuthorizeSSHSign(context.Context, string) ([]provisioner.SignOption, error) {
return nil, errDummyImplementation
}
// AuthorizeSSHRevoke returns an unimplemented error. Provisioners should overwrite
// this method if they will support authorizing tokens for revoking SSH Certificates.
func (s *SCEP) AuthorizeSSHRevoke(context.Context, string) error {
return errDummyImplementation
}
// AuthorizeSSHRenew returns an unimplemented error. Provisioners should overwrite
// this method if they will support authorizing tokens for renewing SSH Certificates.
func (s *SCEP) AuthorizeSSHRenew(context.Context, string) (*ssh.Certificate, error) {
return nil, errDummyImplementation
}
// AuthorizeSSHRekey returns an unimplemented error. Provisioners should overwrite
// this method if they will support authorizing tokens for rekeying SSH Certificates.
func (s *SCEP) AuthorizeSSHRekey(context.Context, string) (*ssh.Certificate, []provisioner.SignOption, error) {
return nil, nil, errDummyImplementation
}
var _ provisioner.Interface = (*SCEP)(nil)

@ -51,7 +51,7 @@ func (e badProtoJSONError) Error() string {
}
// Render implements render.RenderableError for badProtoJSONError
func (e badProtoJSONError) Render(w http.ResponseWriter) {
func (e badProtoJSONError) Render(w http.ResponseWriter, r *http.Request) {
v := struct {
Type string `json:"type"`
Detail string `json:"detail"`
@ -62,5 +62,5 @@ func (e badProtoJSONError) Render(w http.ResponseWriter) {
// trim the proto prefix for the message
Message: strings.TrimSpace(strings.TrimPrefix(e.Error(), "proto:")),
}
render.JSONStatus(w, v, http.StatusBadRequest)
render.JSONStatus(w, r, v, http.StatusBadRequest)
}

@ -142,7 +142,8 @@ func Test_badProtoJSONError_Render(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
w := httptest.NewRecorder()
tt.e.Render(w)
r := httptest.NewRequest("POST", "/test", http.NoBody)
tt.e.Render(w, r)
res := w.Result()
defer res.Body.Close()

@ -29,25 +29,25 @@ func (s *RekeyRequest) Validate() error {
// Rekey is similar to renew except that the certificate will be renewed with new key from csr.
func Rekey(w http.ResponseWriter, r *http.Request) {
if r.TLS == nil || len(r.TLS.PeerCertificates) == 0 {
render.Error(w, errs.BadRequest("missing client certificate"))
render.Error(w, r, errs.BadRequest("missing client certificate"))
return
}
var body RekeyRequest
if err := read.JSON(r.Body, &body); err != nil {
render.Error(w, errs.BadRequestErr(err, "error reading request body"))
render.Error(w, r, errs.BadRequestErr(err, "error reading request body"))
return
}
if err := body.Validate(); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
a := mustAuthority(r.Context())
certChain, err := a.Rekey(r.TLS.PeerCertificates[0], body.CsrPEM.CertificateRequest.PublicKey)
if err != nil {
render.Error(w, errs.Wrap(http.StatusInternalServerError, err, "cahandler.Rekey"))
render.Error(w, r, errs.Wrap(http.StatusInternalServerError, err, "cahandler.Rekey"))
return
}
certChainPEM := certChainToPEM(certChain)
@ -57,7 +57,7 @@ func Rekey(w http.ResponseWriter, r *http.Request) {
}
LogCertificate(w, certChain[0])
render.JSONStatus(w, &SignResponse{
render.JSONStatus(w, r, &SignResponse{
ServerPEM: certChainPEM[0],
CaPEM: caPEM,
CertChainPEM: certChainPEM,

@ -2,7 +2,6 @@
package render
import (
"bytes"
"encoding/json"
"errors"
"net/http"
@ -14,8 +13,8 @@ import (
)
// JSON is shorthand for JSONStatus(w, v, http.StatusOK).
func JSON(w http.ResponseWriter, v interface{}) {
JSONStatus(w, v, http.StatusOK)
func JSON(w http.ResponseWriter, r *http.Request, v interface{}) {
JSONStatus(w, r, v, http.StatusOK)
}
// JSONStatus marshals v into w. It additionally sets the status code of
@ -23,17 +22,28 @@ func JSON(w http.ResponseWriter, v interface{}) {
//
// JSONStatus sets the Content-Type of w to application/json unless one is
// specified.
func JSONStatus(w http.ResponseWriter, v interface{}, status int) {
var b bytes.Buffer
if err := json.NewEncoder(&b).Encode(v); err != nil {
panic(err)
}
func JSONStatus(w http.ResponseWriter, r *http.Request, v interface{}, status int) {
setContentTypeUnlessPresent(w, "application/json")
w.WriteHeader(status)
_, _ = b.WriteTo(w)
log.EnabledResponse(w, v)
if err := json.NewEncoder(w).Encode(v); err != nil {
var errUnsupportedType *json.UnsupportedTypeError
if errors.As(err, &errUnsupportedType) {
panic(err)
}
var errUnsupportedValue *json.UnsupportedValueError
if errors.As(err, &errUnsupportedValue) {
panic(err)
}
var errMarshalError *json.MarshalerError
if errors.As(err, &errMarshalError) {
panic(err)
}
}
log.EnabledResponse(w, r, v)
}
// ProtoJSON is shorthand for ProtoJSONStatus(w, m, http.StatusOK).
@ -70,22 +80,22 @@ func setContentTypeUnlessPresent(w http.ResponseWriter, contentType string) {
type RenderableError interface {
error
Render(http.ResponseWriter)
Render(http.ResponseWriter, *http.Request)
}
// Error marshals the JSON representation of err to w. In case err implements
// RenderableError its own Render method will be called instead.
func Error(w http.ResponseWriter, err error) {
log.Error(w, err)
func Error(rw http.ResponseWriter, r *http.Request, err error) {
log.Error(rw, r, err)
var r RenderableError
if errors.As(err, &r) {
r.Render(w)
var re RenderableError
if errors.As(err, &re) {
re.Render(rw, r)
return
}
JSONStatus(w, err, statusCodeFromError(err))
JSONStatus(rw, r, err, statusCodeFromError(err))
}
// StatusCodedError is the set of errors that implement the basic StatusCode

@ -1,8 +1,10 @@
package render
import (
"encoding/json"
"fmt"
"io"
"math"
"net/http"
"net/http/httptest"
"strconv"
@ -16,8 +18,8 @@ import (
func TestJSON(t *testing.T) {
rec := httptest.NewRecorder()
rw := logging.NewResponseLogger(rec)
JSON(rw, map[string]interface{}{"foo": "bar"})
r := httptest.NewRequest("POST", "/test", http.NoBody)
JSON(rw, r, map[string]interface{}{"foo": "bar"})
assert.Equal(t, http.StatusOK, rec.Result().StatusCode)
assert.Equal(t, "application/json", rec.Header().Get("Content-Type"))
@ -26,10 +28,44 @@ func TestJSON(t *testing.T) {
assert.Empty(t, rw.Fields())
}
func TestJSONPanics(t *testing.T) {
assert.Panics(t, func() {
JSON(httptest.NewRecorder(), make(chan struct{}))
})
func TestJSONPanicsOnUnsupportedType(t *testing.T) {
jsonPanicTest[json.UnsupportedTypeError](t, make(chan struct{}))
}
func TestJSONPanicsOnUnsupportedValue(t *testing.T) {
jsonPanicTest[json.UnsupportedValueError](t, math.NaN())
}
func TestJSONPanicsOnMarshalerError(t *testing.T) {
var v erroneousJSONMarshaler
jsonPanicTest[json.MarshalerError](t, v)
}
type erroneousJSONMarshaler struct{}
func (erroneousJSONMarshaler) MarshalJSON() ([]byte, error) {
return nil, assert.AnError
}
func jsonPanicTest[T json.UnsupportedTypeError | json.UnsupportedValueError | json.MarshalerError](t *testing.T, v any) {
t.Helper()
defer func() {
var err error
if r := recover(); r == nil {
t.Fatal("expected panic")
} else if e, ok := r.(error); !ok {
t.Fatalf("did not panic with an error (%T)", r)
} else {
err = e
}
var e *T
assert.ErrorAs(t, err, &e)
}()
r := httptest.NewRequest("POST", "/test", http.NoBody)
JSON(httptest.NewRecorder(), r, v)
}
type renderableError struct {
@ -41,10 +77,9 @@ func (err renderableError) Error() string {
return err.Message
}
func (err renderableError) Render(w http.ResponseWriter) {
func (err renderableError) Render(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "something/custom")
JSONStatus(w, err, err.Code)
JSONStatus(w, r, err, err.Code)
}
type statusedError struct {
@ -81,8 +116,8 @@ func TestError(t *testing.T) {
t.Run(strconv.Itoa(caseIndex), func(t *testing.T) {
rec := httptest.NewRecorder()
Error(rec, kase.err)
r := httptest.NewRequest("POST", "/test", http.NoBody)
Error(rec, r, kase.err)
assert.Equal(t, kase.code, rec.Result().StatusCode)
assert.Equal(t, kase.body, rec.Body.String())

@ -6,6 +6,7 @@ import (
"strings"
"github.com/smallstep/certificates/api/render"
"github.com/smallstep/certificates/authority"
"github.com/smallstep/certificates/errs"
)
@ -17,16 +18,25 @@ const (
// Renew uses the information of certificate in the TLS connection to create a
// new one.
func Renew(w http.ResponseWriter, r *http.Request) {
cert, err := getPeerCertificate(r)
ctx := r.Context()
// Get the leaf certificate from the peer or the token.
cert, token, err := getPeerCertificate(r)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
a := mustAuthority(r.Context())
certChain, err := a.Renew(cert)
// The token can be used by RAs to renew a certificate.
if token != "" {
ctx = authority.NewTokenContext(ctx, token)
logOtt(w, token)
}
a := mustAuthority(ctx)
certChain, err := a.RenewContext(ctx, cert, nil)
if err != nil {
render.Error(w, errs.Wrap(http.StatusInternalServerError, err, "cahandler.Renew"))
render.Error(w, r, errs.Wrap(http.StatusInternalServerError, err, "cahandler.Renew"))
return
}
certChainPEM := certChainToPEM(certChain)
@ -36,7 +46,7 @@ func Renew(w http.ResponseWriter, r *http.Request) {
}
LogCertificate(w, certChain[0])
render.JSONStatus(w, &SignResponse{
render.JSONStatus(w, r, &SignResponse{
ServerPEM: certChainPEM[0],
CaPEM: caPEM,
CertChainPEM: certChainPEM,
@ -44,15 +54,16 @@ func Renew(w http.ResponseWriter, r *http.Request) {
}, http.StatusCreated)
}
func getPeerCertificate(r *http.Request) (*x509.Certificate, error) {
func getPeerCertificate(r *http.Request) (*x509.Certificate, string, error) {
if r.TLS != nil && len(r.TLS.PeerCertificates) > 0 {
return r.TLS.PeerCertificates[0], nil
return r.TLS.PeerCertificates[0], "", nil
}
if s := r.Header.Get(authorizationHeader); s != "" {
if parts := strings.SplitN(s, bearerScheme+" ", 2); len(parts) == 2 {
ctx := r.Context()
return mustAuthority(ctx).AuthorizeRenewToken(ctx, parts[1])
peer, err := mustAuthority(ctx).AuthorizeRenewToken(ctx, parts[1])
return peer, parts[1], err
}
}
return nil, errs.BadRequest("missing client certificate")
return nil, "", errs.BadRequest("missing client certificate")
}

@ -57,12 +57,12 @@ func (r *RevokeRequest) Validate() (err error) {
func Revoke(w http.ResponseWriter, r *http.Request) {
var body RevokeRequest
if err := read.JSON(r.Body, &body); err != nil {
render.Error(w, errs.BadRequestErr(err, "error reading request body"))
render.Error(w, r, errs.BadRequestErr(err, "error reading request body"))
return
}
if err := body.Validate(); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
@ -78,10 +78,10 @@ func Revoke(w http.ResponseWriter, r *http.Request) {
// A token indicates that we are using the api via a provisioner token,
// otherwise it is assumed that the certificate is revoking itself over mTLS.
if len(body.OTT) > 0 {
if body.OTT != "" {
logOtt(w, body.OTT)
if _, err := a.Authorize(ctx, body.OTT); err != nil {
render.Error(w, errs.UnauthorizedErr(err))
render.Error(w, r, errs.UnauthorizedErr(err))
return
}
opts.OTT = body.OTT
@ -90,12 +90,12 @@ func Revoke(w http.ResponseWriter, r *http.Request) {
// the client certificate Serial Number must match the serial number
// being revoked.
if r.TLS == nil || len(r.TLS.PeerCertificates) == 0 {
render.Error(w, errs.BadRequest("missing ott or client certificate"))
render.Error(w, r, errs.BadRequest("missing ott or client certificate"))
return
}
opts.Crt = r.TLS.PeerCertificates[0]
if opts.Crt.SerialNumber.String() != opts.Serial {
render.Error(w, errs.BadRequest("serial number in client certificate different than body"))
render.Error(w, r, errs.BadRequest("serial number in client certificate different than body"))
return
}
// TODO: should probably be checking if the certificate was revoked here.
@ -106,12 +106,12 @@ func Revoke(w http.ResponseWriter, r *http.Request) {
}
if err := a.Revoke(ctx, opts); err != nil {
render.Error(w, errs.ForbiddenErr(err, "error revoking certificate"))
render.Error(w, r, errs.ForbiddenErr(err, "error revoking certificate"))
return
}
logRevoke(w, opts)
render.JSON(w, &RevokeResponse{Status: "ok"})
render.JSON(w, r, &RevokeResponse{Status: "ok"})
}
func logRevoke(w http.ResponseWriter, ri *authority.RevokeOptions) {

@ -52,13 +52,13 @@ type SignResponse struct {
func Sign(w http.ResponseWriter, r *http.Request) {
var body SignRequest
if err := read.JSON(r.Body, &body); err != nil {
render.Error(w, errs.BadRequestErr(err, "error reading request body"))
render.Error(w, r, errs.BadRequestErr(err, "error reading request body"))
return
}
logOtt(w, body.OTT)
if err := body.Validate(); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
@ -74,13 +74,13 @@ func Sign(w http.ResponseWriter, r *http.Request) {
ctx = provisioner.NewContextWithMethod(ctx, provisioner.SignMethod)
signOpts, err := a.Authorize(ctx, body.OTT)
if err != nil {
render.Error(w, errs.UnauthorizedErr(err))
render.Error(w, r, errs.UnauthorizedErr(err))
return
}
certChain, err := a.Sign(body.CsrPEM.CertificateRequest, opts, signOpts...)
certChain, err := a.SignWithContext(ctx, body.CsrPEM.CertificateRequest, opts, signOpts...)
if err != nil {
render.Error(w, errs.ForbiddenErr(err, "error signing certificate"))
render.Error(w, r, errs.ForbiddenErr(err, "error signing certificate"))
return
}
certChainPEM := certChainToPEM(certChain)
@ -88,8 +88,9 @@ func Sign(w http.ResponseWriter, r *http.Request) {
if len(certChainPEM) > 1 {
caPEM = certChainPEM[1]
}
LogCertificate(w, certChain[0])
render.JSONStatus(w, &SignResponse{
render.JSONStatus(w, r, &SignResponse{
ServerPEM: certChainPEM[0],
CaPEM: caPEM,
CertChainPEM: certChainPEM,

@ -253,19 +253,19 @@ type SSHBastionResponse struct {
func SSHSign(w http.ResponseWriter, r *http.Request) {
var body SSHSignRequest
if err := read.JSON(r.Body, &body); err != nil {
render.Error(w, errs.BadRequestErr(err, "error reading request body"))
render.Error(w, r, errs.BadRequestErr(err, "error reading request body"))
return
}
logOtt(w, body.OTT)
if err := body.Validate(); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
publicKey, err := ssh.ParsePublicKey(body.PublicKey)
if err != nil {
render.Error(w, errs.BadRequestErr(err, "error parsing publicKey"))
render.Error(w, r, errs.BadRequestErr(err, "error parsing publicKey"))
return
}
@ -273,7 +273,7 @@ func SSHSign(w http.ResponseWriter, r *http.Request) {
if body.AddUserPublicKey != nil {
addUserPublicKey, err = ssh.ParsePublicKey(body.AddUserPublicKey)
if err != nil {
render.Error(w, errs.BadRequestErr(err, "error parsing addUserPublicKey"))
render.Error(w, r, errs.BadRequestErr(err, "error parsing addUserPublicKey"))
return
}
}
@ -293,13 +293,13 @@ func SSHSign(w http.ResponseWriter, r *http.Request) {
a := mustAuthority(ctx)
signOpts, err := a.Authorize(ctx, body.OTT)
if err != nil {
render.Error(w, errs.UnauthorizedErr(err))
render.Error(w, r, errs.UnauthorizedErr(err))
return
}
cert, err := a.SignSSH(ctx, publicKey, opts, signOpts...)
if err != nil {
render.Error(w, errs.ForbiddenErr(err, "error signing ssh certificate"))
render.Error(w, r, errs.ForbiddenErr(err, "error signing ssh certificate"))
return
}
@ -307,7 +307,7 @@ func SSHSign(w http.ResponseWriter, r *http.Request) {
if addUserPublicKey != nil && authority.IsValidForAddUser(cert) == nil {
addUserCert, err := a.SignSSHAddUser(ctx, addUserPublicKey, cert)
if err != nil {
render.Error(w, errs.ForbiddenErr(err, "error signing ssh certificate"))
render.Error(w, r, errs.ForbiddenErr(err, "error signing ssh certificate"))
return
}
addUserCertificate = &SSHCertificate{addUserCert}
@ -317,10 +317,10 @@ func SSHSign(w http.ResponseWriter, r *http.Request) {
var identityCertificate []Certificate
if cr := body.IdentityCSR.CertificateRequest; cr != nil {
ctx := authority.NewContextWithSkipTokenReuse(r.Context())
ctx = provisioner.NewContextWithMethod(ctx, provisioner.SignMethod)
ctx = provisioner.NewContextWithMethod(ctx, provisioner.SignIdentityMethod)
signOpts, err := a.Authorize(ctx, body.OTT)
if err != nil {
render.Error(w, errs.UnauthorizedErr(err))
render.Error(w, r, errs.UnauthorizedErr(err))
return
}
@ -330,15 +330,16 @@ func SSHSign(w http.ResponseWriter, r *http.Request) {
NotAfter: time.Unix(int64(cert.ValidBefore), 0),
})
certChain, err := a.Sign(cr, provisioner.SignOptions{}, signOpts...)
certChain, err := a.SignWithContext(ctx, cr, provisioner.SignOptions{}, signOpts...)
if err != nil {
render.Error(w, errs.ForbiddenErr(err, "error signing identity certificate"))
render.Error(w, r, errs.ForbiddenErr(err, "error signing identity certificate"))
return
}
identityCertificate = certChainToPEM(certChain)
}
render.JSONStatus(w, &SSHSignResponse{
LogSSHCertificate(w, cert)
render.JSONStatus(w, r, &SSHSignResponse{
Certificate: SSHCertificate{cert},
AddUserCertificate: addUserCertificate,
IdentityCertificate: identityCertificate,
@ -351,12 +352,12 @@ func SSHRoots(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
keys, err := mustAuthority(ctx).GetSSHRoots(ctx)
if err != nil {
render.Error(w, errs.InternalServerErr(err))
render.Error(w, r, errs.InternalServerErr(err))
return
}
if len(keys.HostKeys) == 0 && len(keys.UserKeys) == 0 {
render.Error(w, errs.NotFound("no keys found"))
render.Error(w, r, errs.NotFound("no keys found"))
return
}
@ -368,7 +369,7 @@ func SSHRoots(w http.ResponseWriter, r *http.Request) {
resp.UserKeys = append(resp.UserKeys, SSHPublicKey{PublicKey: k})
}
render.JSON(w, resp)
render.JSON(w, r, resp)
}
// SSHFederation is an HTTP handler that returns the federated SSH public keys
@ -377,12 +378,12 @@ func SSHFederation(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
keys, err := mustAuthority(ctx).GetSSHFederation(ctx)
if err != nil {
render.Error(w, errs.InternalServerErr(err))
render.Error(w, r, errs.InternalServerErr(err))
return
}
if len(keys.HostKeys) == 0 && len(keys.UserKeys) == 0 {
render.Error(w, errs.NotFound("no keys found"))
render.Error(w, r, errs.NotFound("no keys found"))
return
}
@ -394,7 +395,7 @@ func SSHFederation(w http.ResponseWriter, r *http.Request) {
resp.UserKeys = append(resp.UserKeys, SSHPublicKey{PublicKey: k})
}
render.JSON(w, resp)
render.JSON(w, r, resp)
}
// SSHConfig is an HTTP handler that returns rendered templates for ssh clients
@ -402,18 +403,18 @@ func SSHFederation(w http.ResponseWriter, r *http.Request) {
func SSHConfig(w http.ResponseWriter, r *http.Request) {
var body SSHConfigRequest
if err := read.JSON(r.Body, &body); err != nil {
render.Error(w, errs.BadRequestErr(err, "error reading request body"))
render.Error(w, r, errs.BadRequestErr(err, "error reading request body"))
return
}
if err := body.Validate(); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
ctx := r.Context()
ts, err := mustAuthority(ctx).GetSSHConfig(ctx, body.Type, body.Data)
if err != nil {
render.Error(w, errs.InternalServerErr(err))
render.Error(w, r, errs.InternalServerErr(err))
return
}
@ -424,32 +425,32 @@ func SSHConfig(w http.ResponseWriter, r *http.Request) {
case provisioner.SSHHostCert:
cfg.HostTemplates = ts
default:
render.Error(w, errs.InternalServer("it should hot get here"))
render.Error(w, r, errs.InternalServer("it should hot get here"))
return
}
render.JSON(w, cfg)
render.JSON(w, r, cfg)
}
// SSHCheckHost is the HTTP handler that returns if a hosts certificate exists or not.
func SSHCheckHost(w http.ResponseWriter, r *http.Request) {
var body SSHCheckPrincipalRequest
if err := read.JSON(r.Body, &body); err != nil {
render.Error(w, errs.BadRequestErr(err, "error reading request body"))
render.Error(w, r, errs.BadRequestErr(err, "error reading request body"))
return
}
if err := body.Validate(); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
ctx := r.Context()
exists, err := mustAuthority(ctx).CheckSSHHost(ctx, body.Principal, body.Token)
if err != nil {
render.Error(w, errs.InternalServerErr(err))
render.Error(w, r, errs.InternalServerErr(err))
return
}
render.JSON(w, &SSHCheckPrincipalResponse{
render.JSON(w, r, &SSHCheckPrincipalResponse{
Exists: exists,
})
}
@ -464,10 +465,10 @@ func SSHGetHosts(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
hosts, err := mustAuthority(ctx).GetSSHHosts(ctx, cert)
if err != nil {
render.Error(w, errs.InternalServerErr(err))
render.Error(w, r, errs.InternalServerErr(err))
return
}
render.JSON(w, &SSHGetHostsResponse{
render.JSON(w, r, &SSHGetHostsResponse{
Hosts: hosts,
})
}
@ -476,22 +477,22 @@ func SSHGetHosts(w http.ResponseWriter, r *http.Request) {
func SSHBastion(w http.ResponseWriter, r *http.Request) {
var body SSHBastionRequest
if err := read.JSON(r.Body, &body); err != nil {
render.Error(w, errs.BadRequestErr(err, "error reading request body"))
render.Error(w, r, errs.BadRequestErr(err, "error reading request body"))
return
}
if err := body.Validate(); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
ctx := r.Context()
bastion, err := mustAuthority(ctx).GetSSHBastion(ctx, body.User, body.Hostname)
if err != nil {
render.Error(w, errs.InternalServerErr(err))
render.Error(w, r, errs.InternalServerErr(err))
return
}
render.JSON(w, &SSHBastionResponse{
render.JSON(w, r, &SSHBastionResponse{
Hostname: body.Hostname,
Bastion: bastion,
})

@ -42,19 +42,19 @@ type SSHRekeyResponse struct {
func SSHRekey(w http.ResponseWriter, r *http.Request) {
var body SSHRekeyRequest
if err := read.JSON(r.Body, &body); err != nil {
render.Error(w, errs.BadRequestErr(err, "error reading request body"))
render.Error(w, r, errs.BadRequestErr(err, "error reading request body"))
return
}
logOtt(w, body.OTT)
if err := body.Validate(); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
publicKey, err := ssh.ParsePublicKey(body.PublicKey)
if err != nil {
render.Error(w, errs.BadRequestErr(err, "error parsing publicKey"))
render.Error(w, r, errs.BadRequestErr(err, "error parsing publicKey"))
return
}
@ -64,18 +64,18 @@ func SSHRekey(w http.ResponseWriter, r *http.Request) {
a := mustAuthority(ctx)
signOpts, err := a.Authorize(ctx, body.OTT)
if err != nil {
render.Error(w, errs.UnauthorizedErr(err))
render.Error(w, r, errs.UnauthorizedErr(err))
return
}
oldCert, _, err := provisioner.ExtractSSHPOPCert(body.OTT)
if err != nil {
render.Error(w, errs.InternalServerErr(err))
render.Error(w, r, errs.InternalServerErr(err))
return
}
newCert, err := a.RekeySSH(ctx, oldCert, publicKey, signOpts...)
if err != nil {
render.Error(w, errs.ForbiddenErr(err, "error rekeying ssh certificate"))
render.Error(w, r, errs.ForbiddenErr(err, "error rekeying ssh certificate"))
return
}
@ -85,11 +85,12 @@ func SSHRekey(w http.ResponseWriter, r *http.Request) {
identity, err := renewIdentityCertificate(r, notBefore, notAfter)
if err != nil {
render.Error(w, errs.ForbiddenErr(err, "error renewing identity certificate"))
render.Error(w, r, errs.ForbiddenErr(err, "error renewing identity certificate"))
return
}
render.JSONStatus(w, &SSHRekeyResponse{
LogSSHCertificate(w, newCert)
render.JSONStatus(w, r, &SSHRekeyResponse{
Certificate: SSHCertificate{newCert},
IdentityCertificate: identity,
}, http.StatusCreated)

@ -40,13 +40,13 @@ type SSHRenewResponse struct {
func SSHRenew(w http.ResponseWriter, r *http.Request) {
var body SSHRenewRequest
if err := read.JSON(r.Body, &body); err != nil {
render.Error(w, errs.BadRequestErr(err, "error reading request body"))
render.Error(w, r, errs.BadRequestErr(err, "error reading request body"))
return
}
logOtt(w, body.OTT)
if err := body.Validate(); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
@ -56,18 +56,18 @@ func SSHRenew(w http.ResponseWriter, r *http.Request) {
a := mustAuthority(ctx)
_, err := a.Authorize(ctx, body.OTT)
if err != nil {
render.Error(w, errs.UnauthorizedErr(err))
render.Error(w, r, errs.UnauthorizedErr(err))
return
}
oldCert, _, err := provisioner.ExtractSSHPOPCert(body.OTT)
if err != nil {
render.Error(w, errs.InternalServerErr(err))
render.Error(w, r, errs.InternalServerErr(err))
return
}
newCert, err := a.RenewSSH(ctx, oldCert)
if err != nil {
render.Error(w, errs.ForbiddenErr(err, "error renewing ssh certificate"))
render.Error(w, r, errs.ForbiddenErr(err, "error renewing ssh certificate"))
return
}
@ -77,11 +77,12 @@ func SSHRenew(w http.ResponseWriter, r *http.Request) {
identity, err := renewIdentityCertificate(r, notBefore, notAfter)
if err != nil {
render.Error(w, errs.ForbiddenErr(err, "error renewing identity certificate"))
render.Error(w, r, errs.ForbiddenErr(err, "error renewing identity certificate"))
return
}
render.JSONStatus(w, &SSHSignResponse{
LogSSHCertificate(w, newCert)
render.JSONStatus(w, r, &SSHSignResponse{
Certificate: SSHCertificate{newCert},
IdentityCertificate: identity,
}, http.StatusCreated)

@ -51,12 +51,12 @@ func (r *SSHRevokeRequest) Validate() (err error) {
func SSHRevoke(w http.ResponseWriter, r *http.Request) {
var body SSHRevokeRequest
if err := read.JSON(r.Body, &body); err != nil {
render.Error(w, errs.BadRequestErr(err, "error reading request body"))
render.Error(w, r, errs.BadRequestErr(err, "error reading request body"))
return
}
if err := body.Validate(); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
@ -75,18 +75,18 @@ func SSHRevoke(w http.ResponseWriter, r *http.Request) {
logOtt(w, body.OTT)
if _, err := a.Authorize(ctx, body.OTT); err != nil {
render.Error(w, errs.UnauthorizedErr(err))
render.Error(w, r, errs.UnauthorizedErr(err))
return
}
opts.OTT = body.OTT
if err := a.Revoke(ctx, opts); err != nil {
render.Error(w, errs.ForbiddenErr(err, "error revoking ssh certificate"))
render.Error(w, r, errs.ForbiddenErr(err, "error revoking ssh certificate"))
return
}
logSSHRevoke(w, opts)
render.JSON(w, &SSHRevokeResponse{Status: "ok"})
render.JSON(w, r, &SSHRevokeResponse{Status: "ok"})
}
func logSSHRevoke(w http.ResponseWriter, ri *authority.RevokeOptions) {

@ -325,7 +325,7 @@ func Test_SSHSign(t *testing.T) {
signSSHAddUser: func(ctx context.Context, key ssh.PublicKey, cert *ssh.Certificate) (*ssh.Certificate, error) {
return tt.addUserCert, tt.addUserErr
},
sign: func(cr *x509.CertificateRequest, opts provisioner.SignOptions, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
signWithContext: func(ctx context.Context, cr *x509.CertificateRequest, opts provisioner.SignOptions, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error) {
return tt.tlsSignCerts, tt.tlsSignErr
},
})

@ -40,12 +40,12 @@ func requireEABEnabled(next http.HandlerFunc) http.HandlerFunc {
acmeProvisioner := prov.GetDetails().GetACME()
if acmeProvisioner == nil {
render.Error(w, admin.NewErrorISE("error getting ACME details for provisioner '%s'", prov.GetName()))
render.Error(w, r, admin.NewErrorISE("error getting ACME details for provisioner '%s'", prov.GetName()))
return
}
if !acmeProvisioner.RequireEab {
render.Error(w, admin.NewError(admin.ErrorBadRequestType, "ACME EAB not enabled for provisioner '%s'", prov.GetName()))
render.Error(w, r, admin.NewError(admin.ErrorBadRequestType, "ACME EAB not enabled for provisioner '%s'", prov.GetName()))
return
}
@ -70,17 +70,17 @@ func NewACMEAdminResponder() ACMEAdminResponder {
// GetExternalAccountKeys writes the response for the EAB keys GET endpoint
func (h *acmeAdminResponder) GetExternalAccountKeys(w http.ResponseWriter, r *http.Request) {
render.Error(w, admin.NewError(admin.ErrorNotImplementedType, "this functionality is currently only available in Certificate Manager: https://u.step.sm/cm"))
render.Error(w, r, admin.NewError(admin.ErrorNotImplementedType, "this functionality is currently only available in Certificate Manager: https://u.step.sm/cm"))
}
// CreateExternalAccountKey writes the response for the EAB key POST endpoint
func (h *acmeAdminResponder) CreateExternalAccountKey(w http.ResponseWriter, r *http.Request) {
render.Error(w, admin.NewError(admin.ErrorNotImplementedType, "this functionality is currently only available in Certificate Manager: https://u.step.sm/cm"))
render.Error(w, r, admin.NewError(admin.ErrorNotImplementedType, "this functionality is currently only available in Certificate Manager: https://u.step.sm/cm"))
}
// DeleteExternalAccountKey writes the response for the EAB key DELETE endpoint
func (h *acmeAdminResponder) DeleteExternalAccountKey(w http.ResponseWriter, r *http.Request) {
render.Error(w, admin.NewError(admin.ErrorNotImplementedType, "this functionality is currently only available in Certificate Manager: https://u.step.sm/cm"))
render.Error(w, r, admin.NewError(admin.ErrorNotImplementedType, "this functionality is currently only available in Certificate Manager: https://u.step.sm/cm"))
}
func eakToLinked(k *acme.ExternalAccountKey) *linkedca.EABKey {

@ -12,7 +12,7 @@ import (
"testing"
"time"
"github.com/go-chi/chi"
"github.com/go-chi/chi/v5"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/timestamppb"
@ -128,7 +128,7 @@ func TestHandler_requireEABEnabled(t *testing.T) {
for name, prep := range tests {
tc := prep(t)
t.Run(name, func(t *testing.T) {
req := httptest.NewRequest("GET", "/foo", nil).WithContext(tc.ctx)
req := httptest.NewRequest("GET", "/foo", http.NoBody).WithContext(tc.ctx)
w := httptest.NewRecorder()
requireEABEnabled(tc.next)(w, req)
res := w.Result()
@ -223,7 +223,7 @@ func TestHandler_CreateExternalAccountKey(t *testing.T) {
tc := prep(t)
t.Run(name, func(t *testing.T) {
req := httptest.NewRequest("POST", "/foo", nil) // chi routing is prepared in test setup
req := httptest.NewRequest("POST", "/foo", http.NoBody) // chi routing is prepared in test setup
req = req.WithContext(tc.ctx)
w := httptest.NewRecorder()
acmeResponder := NewACMEAdminResponder()
@ -276,7 +276,7 @@ func TestHandler_DeleteExternalAccountKey(t *testing.T) {
tc := prep(t)
t.Run(name, func(t *testing.T) {
req := httptest.NewRequest("DELETE", "/foo", nil) // chi routing is prepared in test setup
req := httptest.NewRequest("DELETE", "/foo", http.NoBody) // chi routing is prepared in test setup
req = req.WithContext(tc.ctx)
w := httptest.NewRecorder()
acmeResponder := NewACMEAdminResponder()
@ -311,7 +311,7 @@ func TestHandler_GetExternalAccountKeys(t *testing.T) {
"ok": func(t *testing.T) test {
chiCtx := chi.NewRouteContext()
chiCtx.URLParams.Add("provisionerName", "provName")
req := httptest.NewRequest("GET", "/foo", nil)
req := httptest.NewRequest("GET", "/foo", http.NoBody)
ctx := context.WithValue(context.Background(), chi.RouteCtxKey, chiCtx)
return test{
ctx: ctx,

@ -4,7 +4,7 @@ import (
"context"
"net/http"
"github.com/go-chi/chi"
"github.com/go-chi/chi/v5"
"go.step.sm/linkedca"
@ -90,7 +90,7 @@ func GetAdmin(w http.ResponseWriter, r *http.Request) {
adm, ok := mustAuthority(r.Context()).LoadAdminByID(id)
if !ok {
render.Error(w, admin.NewError(admin.ErrorNotFoundType,
render.Error(w, r, admin.NewError(admin.ErrorNotFoundType,
"admin %s not found", id))
return
}
@ -101,17 +101,17 @@ func GetAdmin(w http.ResponseWriter, r *http.Request) {
func GetAdmins(w http.ResponseWriter, r *http.Request) {
cursor, limit, err := api.ParseCursor(r)
if err != nil {
render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err,
render.Error(w, r, admin.WrapError(admin.ErrorBadRequestType, err,
"error parsing cursor and limit from query params"))
return
}
admins, nextCursor, err := mustAuthority(r.Context()).GetAdmins(cursor, limit)
if err != nil {
render.Error(w, admin.WrapErrorISE(err, "error retrieving paginated admins"))
render.Error(w, r, admin.WrapErrorISE(err, "error retrieving paginated admins"))
return
}
render.JSON(w, &GetAdminsResponse{
render.JSON(w, r, &GetAdminsResponse{
Admins: admins,
NextCursor: nextCursor,
})
@ -121,19 +121,19 @@ func GetAdmins(w http.ResponseWriter, r *http.Request) {
func CreateAdmin(w http.ResponseWriter, r *http.Request) {
var body CreateAdminRequest
if err := read.JSON(r.Body, &body); err != nil {
render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err, "error reading request body"))
render.Error(w, r, admin.WrapError(admin.ErrorBadRequestType, err, "error reading request body"))
return
}
if err := body.Validate(); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
auth := mustAuthority(r.Context())
p, err := auth.LoadProvisionerByName(body.Provisioner)
if err != nil {
render.Error(w, admin.WrapErrorISE(err, "error loading provisioner %s", body.Provisioner))
render.Error(w, r, admin.WrapErrorISE(err, "error loading provisioner %s", body.Provisioner))
return
}
adm := &linkedca.Admin{
@ -143,7 +143,7 @@ func CreateAdmin(w http.ResponseWriter, r *http.Request) {
}
// Store to authority collection.
if err := auth.StoreAdmin(r.Context(), adm, p); err != nil {
render.Error(w, admin.WrapErrorISE(err, "error storing admin"))
render.Error(w, r, admin.WrapErrorISE(err, "error storing admin"))
return
}
@ -155,23 +155,23 @@ func DeleteAdmin(w http.ResponseWriter, r *http.Request) {
id := chi.URLParam(r, "id")
if err := mustAuthority(r.Context()).RemoveAdmin(r.Context(), id); err != nil {
render.Error(w, admin.WrapErrorISE(err, "error deleting admin %s", id))
render.Error(w, r, admin.WrapErrorISE(err, "error deleting admin %s", id))
return
}
render.JSON(w, &DeleteResponse{Status: "ok"})
render.JSON(w, r, &DeleteResponse{Status: "ok"})
}
// UpdateAdmin updates an existing admin.
func UpdateAdmin(w http.ResponseWriter, r *http.Request) {
var body UpdateAdminRequest
if err := read.JSON(r.Body, &body); err != nil {
render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err, "error reading request body"))
render.Error(w, r, admin.WrapError(admin.ErrorBadRequestType, err, "error reading request body"))
return
}
if err := body.Validate(); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
@ -179,7 +179,7 @@ func UpdateAdmin(w http.ResponseWriter, r *http.Request) {
auth := mustAuthority(r.Context())
adm, err := auth.UpdateAdmin(r.Context(), id, &linkedca.Admin{Type: body.Type})
if err != nil {
render.Error(w, admin.WrapErrorISE(err, "error updating admin %s", id))
render.Error(w, r, admin.WrapErrorISE(err, "error updating admin %s", id))
return
}

@ -11,7 +11,7 @@ import (
"testing"
"time"
"github.com/go-chi/chi"
"github.com/go-chi/chi/v5"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"google.golang.org/protobuf/types/known/timestamppb"
@ -357,7 +357,7 @@ func TestHandler_GetAdmin(t *testing.T) {
tc := prep(t)
t.Run(name, func(t *testing.T) {
mockMustAuthority(t, tc.auth)
req := httptest.NewRequest("GET", "/foo", nil) // chi routing is prepared in test setup
req := httptest.NewRequest("GET", "/foo", http.NoBody) // chi routing is prepared in test setup
req = req.WithContext(tc.ctx)
w := httptest.NewRecorder()
GetAdmin(w, req)
@ -406,7 +406,7 @@ func TestHandler_GetAdmins(t *testing.T) {
}
var tests = map[string]func(t *testing.T) test{
"fail/parse-cursor": func(t *testing.T) test {
req := httptest.NewRequest("GET", "/foo?limit=A", nil)
req := httptest.NewRequest("GET", "/foo?limit=A", http.NoBody)
return test{
ctx: context.Background(),
req: req,
@ -420,7 +420,7 @@ func TestHandler_GetAdmins(t *testing.T) {
}
},
"fail/auth.GetAdmins": func(t *testing.T) test {
req := httptest.NewRequest("GET", "/foo", nil)
req := httptest.NewRequest("GET", "/foo", http.NoBody)
auth := &mockAdminAuthority{
MockGetAdmins: func(cursor string, limit int) ([]*linkedca.Admin, string, error) {
assert.Equals(t, "", cursor)
@ -442,7 +442,7 @@ func TestHandler_GetAdmins(t *testing.T) {
}
},
"ok": func(t *testing.T) test {
req := httptest.NewRequest("GET", "/foo", nil)
req := httptest.NewRequest("GET", "/foo", http.NoBody)
createdAt := time.Now()
var deletedAt time.Time
adm1 := &linkedca.Admin{
@ -764,7 +764,7 @@ func TestHandler_DeleteAdmin(t *testing.T) {
tc := prep(t)
t.Run(name, func(t *testing.T) {
mockMustAuthority(t, tc.auth)
req := httptest.NewRequest("DELETE", "/foo", nil) // chi routing is prepared in test setup
req := httptest.NewRequest("DELETE", "/foo", http.NoBody) // chi routing is prepared in test setup
req = req.WithContext(tc.ctx)
w := httptest.NewRecorder()
DeleteAdmin(w, req)

@ -1,10 +1,9 @@
package api
import (
"errors"
"net/http"
"github.com/go-chi/chi"
"github.com/go-chi/chi/v5"
"go.step.sm/linkedca"
@ -20,7 +19,7 @@ import (
func requireAPIEnabled(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if !mustAuthority(r.Context()).IsAdminAPIEnabled() {
render.Error(w, admin.NewError(admin.ErrorNotImplementedType, "administration API not enabled"))
render.Error(w, r, admin.NewError(admin.ErrorNotImplementedType, "administration API not enabled"))
return
}
next(w, r)
@ -32,7 +31,7 @@ func extractAuthorizeTokenAdmin(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
tok := r.Header.Get("Authorization")
if tok == "" {
render.Error(w, admin.NewError(admin.ErrorUnauthorizedType,
render.Error(w, r, admin.NewError(admin.ErrorUnauthorizedType,
"missing authorization header token"))
return
}
@ -40,7 +39,7 @@ func extractAuthorizeTokenAdmin(next http.HandlerFunc) http.HandlerFunc {
ctx := r.Context()
adm, err := mustAuthority(ctx).AuthorizeAdminToken(r, tok)
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
@ -65,13 +64,13 @@ func loadProvisionerByName(next http.HandlerFunc) http.HandlerFunc {
// TODO(hs): distinguish 404 vs. 500
if p, err = auth.LoadProvisionerByName(name); err != nil {
render.Error(w, admin.WrapErrorISE(err, "error loading provisioner %s", name))
render.Error(w, r, admin.WrapErrorISE(err, "error loading provisioner %s", name))
return
}
prov, err := adminDB.GetProvisioner(ctx, p.GetID())
if err != nil {
render.Error(w, admin.WrapErrorISE(err, "error retrieving provisioner %s", name))
render.Error(w, r, admin.WrapErrorISE(err, "error retrieving provisioner %s", name))
return
}
@ -92,7 +91,7 @@ func checkAction(next http.HandlerFunc, supportedInStandalone bool) http.Handler
// when an action is not supported in standalone mode and when
// using a nosql.DB backend, actions are not supported
if _, ok := admin.MustFromContext(r.Context()).(*nosql.DB); ok {
render.Error(w, admin.NewError(admin.ErrorNotImplementedType,
render.Error(w, r, admin.NewError(admin.ErrorNotImplementedType,
"operation not supported in standalone mode"))
return
}
@ -125,16 +124,16 @@ func loadExternalAccountKey(next http.HandlerFunc) http.HandlerFunc {
}
if err != nil {
if errors.Is(err, acme.ErrNotFound) {
render.Error(w, admin.NewError(admin.ErrorNotFoundType, "ACME External Account Key not found"))
if acme.IsErrNotFound(err) {
render.Error(w, r, admin.NewError(admin.ErrorNotFoundType, "ACME External Account Key not found"))
return
}
render.Error(w, admin.WrapErrorISE(err, "error retrieving ACME External Account Key"))
render.Error(w, r, admin.WrapErrorISE(err, "error retrieving ACME External Account Key"))
return
}
if eak == nil {
render.Error(w, admin.NewError(admin.ErrorNotFoundType, "ACME External Account Key not found"))
render.Error(w, r, admin.NewError(admin.ErrorNotFoundType, "ACME External Account Key not found"))
return
}

@ -11,7 +11,7 @@ import (
"testing"
"time"
"github.com/go-chi/chi"
"github.com/go-chi/chi/v5"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"google.golang.org/protobuf/types/known/timestamppb"
@ -72,7 +72,7 @@ func TestHandler_requireAPIEnabled(t *testing.T) {
tc := prep(t)
t.Run(name, func(t *testing.T) {
mockMustAuthority(t, tc.auth)
req := httptest.NewRequest("GET", "/foo", nil) // chi routing is prepared in test setup
req := httptest.NewRequest("GET", "/foo", http.NoBody) // chi routing is prepared in test setup
req = req.WithContext(tc.ctx)
w := httptest.NewRecorder()
requireAPIEnabled(tc.next)(w, req)
@ -113,7 +113,7 @@ func TestHandler_extractAuthorizeTokenAdmin(t *testing.T) {
}
var tests = map[string]func(t *testing.T) test{
"fail/missing-authorization-token": func(t *testing.T) test {
req := httptest.NewRequest("GET", "/foo", nil)
req := httptest.NewRequest("GET", "/foo", http.NoBody)
req.Header["Authorization"] = []string{""}
return test{
ctx: context.Background(),
@ -128,7 +128,7 @@ func TestHandler_extractAuthorizeTokenAdmin(t *testing.T) {
}
},
"fail/auth.AuthorizeAdminToken": func(t *testing.T) test {
req := httptest.NewRequest("GET", "/foo", nil)
req := httptest.NewRequest("GET", "/foo", http.NoBody)
req.Header["Authorization"] = []string{"token"}
auth := &mockAdminAuthority{
MockAuthorizeAdminToken: func(r *http.Request, token string) (*linkedca.Admin, error) {
@ -153,7 +153,7 @@ func TestHandler_extractAuthorizeTokenAdmin(t *testing.T) {
}
},
"ok": func(t *testing.T) test {
req := httptest.NewRequest("GET", "/foo", nil)
req := httptest.NewRequest("GET", "/foo", http.NoBody)
req.Header["Authorization"] = []string{"token"}
createdAt := time.Now()
var deletedAt time.Time
@ -324,7 +324,7 @@ func TestHandler_loadProvisionerByName(t *testing.T) {
t.Run(name, func(t *testing.T) {
mockMustAuthority(t, tc.auth)
ctx := admin.NewContext(tc.ctx, tc.adminDB)
req := httptest.NewRequest("GET", "/foo", nil) // chi routing is prepared in test setup
req := httptest.NewRequest("GET", "/foo", http.NoBody) // chi routing is prepared in test setup
req = req.WithContext(ctx)
w := httptest.NewRecorder()
@ -399,7 +399,7 @@ func TestHandler_checkAction(t *testing.T) {
tc := prep(t)
t.Run(name, func(t *testing.T) {
ctx := admin.NewContext(context.Background(), tc.adminDB)
req := httptest.NewRequest("GET", "/foo", nil).WithContext(ctx)
req := httptest.NewRequest("GET", "/foo", http.NoBody).WithContext(ctx)
w := httptest.NewRecorder()
checkAction(tc.next, tc.supportedInStandalone)(w, req)
res := w.Result()
@ -643,7 +643,7 @@ func TestHandler_loadExternalAccountKey(t *testing.T) {
tc := prep(t)
t.Run(name, func(t *testing.T) {
ctx := acme.NewDatabaseContext(tc.ctx, tc.acmeDB)
req := httptest.NewRequest("GET", "/foo", nil)
req := httptest.NewRequest("GET", "/foo", http.NoBody)
req = req.WithContext(ctx)
w := httptest.NewRecorder()
loadExternalAccountKey(tc.next)(w, req)

@ -35,7 +35,7 @@ type PolicyAdminResponder interface {
// policyAdminResponder implements PolicyAdminResponder.
type policyAdminResponder struct{}
// NewACMEAdminResponder returns a new PolicyAdminResponder.
// NewPolicyAdminResponder returns a new PolicyAdminResponder.
func NewPolicyAdminResponder() PolicyAdminResponder {
return &policyAdminResponder{}
}
@ -44,7 +44,7 @@ func NewPolicyAdminResponder() PolicyAdminResponder {
func (par *policyAdminResponder) GetAuthorityPolicy(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if err := blockLinkedCA(ctx); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
@ -52,12 +52,12 @@ func (par *policyAdminResponder) GetAuthorityPolicy(w http.ResponseWriter, r *ht
authorityPolicy, err := auth.GetAuthorityPolicy(r.Context())
var ae *admin.Error
if errors.As(err, &ae) && !ae.IsType(admin.ErrorNotFoundType) {
render.Error(w, admin.WrapErrorISE(ae, "error retrieving authority policy"))
render.Error(w, r, admin.WrapErrorISE(ae, "error retrieving authority policy"))
return
}
if authorityPolicy == nil {
render.Error(w, admin.NewError(admin.ErrorNotFoundType, "authority policy does not exist"))
render.Error(w, r, admin.NewError(admin.ErrorNotFoundType, "authority policy does not exist"))
return
}
@ -68,7 +68,7 @@ func (par *policyAdminResponder) GetAuthorityPolicy(w http.ResponseWriter, r *ht
func (par *policyAdminResponder) CreateAuthorityPolicy(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if err := blockLinkedCA(ctx); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
@ -77,26 +77,26 @@ func (par *policyAdminResponder) CreateAuthorityPolicy(w http.ResponseWriter, r
var ae *admin.Error
if errors.As(err, &ae) && !ae.IsType(admin.ErrorNotFoundType) {
render.Error(w, admin.WrapErrorISE(err, "error retrieving authority policy"))
render.Error(w, r, admin.WrapErrorISE(err, "error retrieving authority policy"))
return
}
if authorityPolicy != nil {
adminErr := admin.NewError(admin.ErrorConflictType, "authority already has a policy")
render.Error(w, adminErr)
render.Error(w, r, adminErr)
return
}
var newPolicy = new(linkedca.Policy)
if err := read.ProtoJSON(r.Body, newPolicy); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
newPolicy.Deduplicate()
if err := validatePolicy(newPolicy); err != nil {
render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err, "error validating authority policy"))
render.Error(w, r, admin.WrapError(admin.ErrorBadRequestType, err, "error validating authority policy"))
return
}
@ -105,11 +105,11 @@ func (par *policyAdminResponder) CreateAuthorityPolicy(w http.ResponseWriter, r
var createdPolicy *linkedca.Policy
if createdPolicy, err = auth.CreateAuthorityPolicy(ctx, adm, newPolicy); err != nil {
if isBadRequest(err) {
render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err, "error storing authority policy"))
render.Error(w, r, admin.WrapError(admin.ErrorBadRequestType, err, "error storing authority policy"))
return
}
render.Error(w, admin.WrapErrorISE(err, "error storing authority policy"))
render.Error(w, r, admin.WrapErrorISE(err, "error storing authority policy"))
return
}
@ -120,7 +120,7 @@ func (par *policyAdminResponder) CreateAuthorityPolicy(w http.ResponseWriter, r
func (par *policyAdminResponder) UpdateAuthorityPolicy(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if err := blockLinkedCA(ctx); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
@ -129,25 +129,25 @@ func (par *policyAdminResponder) UpdateAuthorityPolicy(w http.ResponseWriter, r
var ae *admin.Error
if errors.As(err, &ae) && !ae.IsType(admin.ErrorNotFoundType) {
render.Error(w, admin.WrapErrorISE(err, "error retrieving authority policy"))
render.Error(w, r, admin.WrapErrorISE(err, "error retrieving authority policy"))
return
}
if authorityPolicy == nil {
render.Error(w, admin.NewError(admin.ErrorNotFoundType, "authority policy does not exist"))
render.Error(w, r, admin.NewError(admin.ErrorNotFoundType, "authority policy does not exist"))
return
}
var newPolicy = new(linkedca.Policy)
if err := read.ProtoJSON(r.Body, newPolicy); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
newPolicy.Deduplicate()
if err := validatePolicy(newPolicy); err != nil {
render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err, "error validating authority policy"))
render.Error(w, r, admin.WrapError(admin.ErrorBadRequestType, err, "error validating authority policy"))
return
}
@ -156,11 +156,11 @@ func (par *policyAdminResponder) UpdateAuthorityPolicy(w http.ResponseWriter, r
var updatedPolicy *linkedca.Policy
if updatedPolicy, err = auth.UpdateAuthorityPolicy(ctx, adm, newPolicy); err != nil {
if isBadRequest(err) {
render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err, "error updating authority policy"))
render.Error(w, r, admin.WrapError(admin.ErrorBadRequestType, err, "error updating authority policy"))
return
}
render.Error(w, admin.WrapErrorISE(err, "error updating authority policy"))
render.Error(w, r, admin.WrapErrorISE(err, "error updating authority policy"))
return
}
@ -171,7 +171,7 @@ func (par *policyAdminResponder) UpdateAuthorityPolicy(w http.ResponseWriter, r
func (par *policyAdminResponder) DeleteAuthorityPolicy(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if err := blockLinkedCA(ctx); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
@ -180,35 +180,35 @@ func (par *policyAdminResponder) DeleteAuthorityPolicy(w http.ResponseWriter, r
var ae *admin.Error
if errors.As(err, &ae) && !ae.IsType(admin.ErrorNotFoundType) {
render.Error(w, admin.WrapErrorISE(ae, "error retrieving authority policy"))
render.Error(w, r, admin.WrapErrorISE(ae, "error retrieving authority policy"))
return
}
if authorityPolicy == nil {
render.Error(w, admin.NewError(admin.ErrorNotFoundType, "authority policy does not exist"))
render.Error(w, r, admin.NewError(admin.ErrorNotFoundType, "authority policy does not exist"))
return
}
if err := auth.RemoveAuthorityPolicy(ctx); err != nil {
render.Error(w, admin.WrapErrorISE(err, "error deleting authority policy"))
render.Error(w, r, admin.WrapErrorISE(err, "error deleting authority policy"))
return
}
render.JSONStatus(w, DeleteResponse{Status: "ok"}, http.StatusOK)
render.JSONStatus(w, r, DeleteResponse{Status: "ok"}, http.StatusOK)
}
// GetProvisionerPolicy handles the GET /admin/provisioners/{name}/policy request
func (par *policyAdminResponder) GetProvisionerPolicy(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if err := blockLinkedCA(ctx); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
prov := linkedca.MustProvisionerFromContext(ctx)
provisionerPolicy := prov.GetPolicy()
if provisionerPolicy == nil {
render.Error(w, admin.NewError(admin.ErrorNotFoundType, "provisioner policy does not exist"))
render.Error(w, r, admin.NewError(admin.ErrorNotFoundType, "provisioner policy does not exist"))
return
}
@ -219,7 +219,7 @@ func (par *policyAdminResponder) GetProvisionerPolicy(w http.ResponseWriter, r *
func (par *policyAdminResponder) CreateProvisionerPolicy(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if err := blockLinkedCA(ctx); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
@ -227,20 +227,20 @@ func (par *policyAdminResponder) CreateProvisionerPolicy(w http.ResponseWriter,
provisionerPolicy := prov.GetPolicy()
if provisionerPolicy != nil {
adminErr := admin.NewError(admin.ErrorConflictType, "provisioner %s already has a policy", prov.Name)
render.Error(w, adminErr)
render.Error(w, r, adminErr)
return
}
var newPolicy = new(linkedca.Policy)
if err := read.ProtoJSON(r.Body, newPolicy); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
newPolicy.Deduplicate()
if err := validatePolicy(newPolicy); err != nil {
render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err, "error validating provisioner policy"))
render.Error(w, r, admin.WrapError(admin.ErrorBadRequestType, err, "error validating provisioner policy"))
return
}
@ -248,11 +248,11 @@ func (par *policyAdminResponder) CreateProvisionerPolicy(w http.ResponseWriter,
auth := mustAuthority(ctx)
if err := auth.UpdateProvisioner(ctx, prov); err != nil {
if isBadRequest(err) {
render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err, "error creating provisioner policy"))
render.Error(w, r, admin.WrapError(admin.ErrorBadRequestType, err, "error creating provisioner policy"))
return
}
render.Error(w, admin.WrapErrorISE(err, "error creating provisioner policy"))
render.Error(w, r, admin.WrapErrorISE(err, "error creating provisioner policy"))
return
}
@ -263,27 +263,27 @@ func (par *policyAdminResponder) CreateProvisionerPolicy(w http.ResponseWriter,
func (par *policyAdminResponder) UpdateProvisionerPolicy(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if err := blockLinkedCA(ctx); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
prov := linkedca.MustProvisionerFromContext(ctx)
provisionerPolicy := prov.GetPolicy()
if provisionerPolicy == nil {
render.Error(w, admin.NewError(admin.ErrorNotFoundType, "provisioner policy does not exist"))
render.Error(w, r, admin.NewError(admin.ErrorNotFoundType, "provisioner policy does not exist"))
return
}
var newPolicy = new(linkedca.Policy)
if err := read.ProtoJSON(r.Body, newPolicy); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
newPolicy.Deduplicate()
if err := validatePolicy(newPolicy); err != nil {
render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err, "error validating provisioner policy"))
render.Error(w, r, admin.WrapError(admin.ErrorBadRequestType, err, "error validating provisioner policy"))
return
}
@ -291,11 +291,11 @@ func (par *policyAdminResponder) UpdateProvisionerPolicy(w http.ResponseWriter,
auth := mustAuthority(ctx)
if err := auth.UpdateProvisioner(ctx, prov); err != nil {
if isBadRequest(err) {
render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err, "error updating provisioner policy"))
render.Error(w, r, admin.WrapError(admin.ErrorBadRequestType, err, "error updating provisioner policy"))
return
}
render.Error(w, admin.WrapErrorISE(err, "error updating provisioner policy"))
render.Error(w, r, admin.WrapErrorISE(err, "error updating provisioner policy"))
return
}
@ -306,13 +306,13 @@ func (par *policyAdminResponder) UpdateProvisionerPolicy(w http.ResponseWriter,
func (par *policyAdminResponder) DeleteProvisionerPolicy(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if err := blockLinkedCA(ctx); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
prov := linkedca.MustProvisionerFromContext(ctx)
if prov.Policy == nil {
render.Error(w, admin.NewError(admin.ErrorNotFoundType, "provisioner policy does not exist"))
render.Error(w, r, admin.NewError(admin.ErrorNotFoundType, "provisioner policy does not exist"))
return
}
@ -321,24 +321,24 @@ func (par *policyAdminResponder) DeleteProvisionerPolicy(w http.ResponseWriter,
auth := mustAuthority(ctx)
if err := auth.UpdateProvisioner(ctx, prov); err != nil {
render.Error(w, admin.WrapErrorISE(err, "error deleting provisioner policy"))
render.Error(w, r, admin.WrapErrorISE(err, "error deleting provisioner policy"))
return
}
render.JSONStatus(w, DeleteResponse{Status: "ok"}, http.StatusOK)
render.JSONStatus(w, r, DeleteResponse{Status: "ok"}, http.StatusOK)
}
func (par *policyAdminResponder) GetACMEAccountPolicy(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if err := blockLinkedCA(ctx); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
eak := linkedca.MustExternalAccountKeyFromContext(ctx)
eakPolicy := eak.GetPolicy()
if eakPolicy == nil {
render.Error(w, admin.NewError(admin.ErrorNotFoundType, "ACME EAK policy does not exist"))
render.Error(w, r, admin.NewError(admin.ErrorNotFoundType, "ACME EAK policy does not exist"))
return
}
@ -348,7 +348,7 @@ func (par *policyAdminResponder) GetACMEAccountPolicy(w http.ResponseWriter, r *
func (par *policyAdminResponder) CreateACMEAccountPolicy(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if err := blockLinkedCA(ctx); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
@ -357,20 +357,20 @@ func (par *policyAdminResponder) CreateACMEAccountPolicy(w http.ResponseWriter,
eakPolicy := eak.GetPolicy()
if eakPolicy != nil {
adminErr := admin.NewError(admin.ErrorConflictType, "ACME EAK %s already has a policy", eak.Id)
render.Error(w, adminErr)
render.Error(w, r, adminErr)
return
}
var newPolicy = new(linkedca.Policy)
if err := read.ProtoJSON(r.Body, newPolicy); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
newPolicy.Deduplicate()
if err := validatePolicy(newPolicy); err != nil {
render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err, "error validating ACME EAK policy"))
render.Error(w, r, admin.WrapError(admin.ErrorBadRequestType, err, "error validating ACME EAK policy"))
return
}
@ -379,7 +379,7 @@ func (par *policyAdminResponder) CreateACMEAccountPolicy(w http.ResponseWriter,
acmeEAK := linkedEAKToCertificates(eak)
acmeDB := acme.MustDatabaseFromContext(ctx)
if err := acmeDB.UpdateExternalAccountKey(ctx, prov.GetId(), acmeEAK); err != nil {
render.Error(w, admin.WrapErrorISE(err, "error creating ACME EAK policy"))
render.Error(w, r, admin.WrapErrorISE(err, "error creating ACME EAK policy"))
return
}
@ -389,7 +389,7 @@ func (par *policyAdminResponder) CreateACMEAccountPolicy(w http.ResponseWriter,
func (par *policyAdminResponder) UpdateACMEAccountPolicy(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if err := blockLinkedCA(ctx); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
@ -397,20 +397,20 @@ func (par *policyAdminResponder) UpdateACMEAccountPolicy(w http.ResponseWriter,
eak := linkedca.MustExternalAccountKeyFromContext(ctx)
eakPolicy := eak.GetPolicy()
if eakPolicy == nil {
render.Error(w, admin.NewError(admin.ErrorNotFoundType, "ACME EAK policy does not exist"))
render.Error(w, r, admin.NewError(admin.ErrorNotFoundType, "ACME EAK policy does not exist"))
return
}
var newPolicy = new(linkedca.Policy)
if err := read.ProtoJSON(r.Body, newPolicy); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
newPolicy.Deduplicate()
if err := validatePolicy(newPolicy); err != nil {
render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err, "error validating ACME EAK policy"))
render.Error(w, r, admin.WrapError(admin.ErrorBadRequestType, err, "error validating ACME EAK policy"))
return
}
@ -418,7 +418,7 @@ func (par *policyAdminResponder) UpdateACMEAccountPolicy(w http.ResponseWriter,
acmeEAK := linkedEAKToCertificates(eak)
acmeDB := acme.MustDatabaseFromContext(ctx)
if err := acmeDB.UpdateExternalAccountKey(ctx, prov.GetId(), acmeEAK); err != nil {
render.Error(w, admin.WrapErrorISE(err, "error updating ACME EAK policy"))
render.Error(w, r, admin.WrapErrorISE(err, "error updating ACME EAK policy"))
return
}
@ -428,7 +428,7 @@ func (par *policyAdminResponder) UpdateACMEAccountPolicy(w http.ResponseWriter,
func (par *policyAdminResponder) DeleteACMEAccountPolicy(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if err := blockLinkedCA(ctx); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
@ -436,7 +436,7 @@ func (par *policyAdminResponder) DeleteACMEAccountPolicy(w http.ResponseWriter,
eak := linkedca.MustExternalAccountKeyFromContext(ctx)
eakPolicy := eak.GetPolicy()
if eakPolicy == nil {
render.Error(w, admin.NewError(admin.ErrorNotFoundType, "ACME EAK policy does not exist"))
render.Error(w, r, admin.NewError(admin.ErrorNotFoundType, "ACME EAK policy does not exist"))
return
}
@ -446,11 +446,11 @@ func (par *policyAdminResponder) DeleteACMEAccountPolicy(w http.ResponseWriter,
acmeEAK := linkedEAKToCertificates(eak)
acmeDB := acme.MustDatabaseFromContext(ctx)
if err := acmeDB.UpdateExternalAccountKey(ctx, prov.GetId(), acmeEAK); err != nil {
render.Error(w, admin.WrapErrorISE(err, "error deleting ACME EAK policy"))
render.Error(w, r, admin.WrapErrorISE(err, "error deleting ACME EAK policy"))
return
}
render.JSONStatus(w, DeleteResponse{Status: "ok"}, http.StatusOK)
render.JSONStatus(w, r, DeleteResponse{Status: "ok"}, http.StatusOK)
}
// blockLinkedCA blocks all API operations on linked deployments

@ -241,7 +241,7 @@ func TestPolicyAdminResponder_GetAuthorityPolicy(t *testing.T) {
ctx := admin.NewContext(tc.ctx, tc.adminDB)
par := NewPolicyAdminResponder()
req := httptest.NewRequest("GET", "/foo", nil)
req := httptest.NewRequest("GET", "/foo", http.NoBody)
req = req.WithContext(ctx)
w := httptest.NewRecorder()
@ -1164,7 +1164,7 @@ func TestPolicyAdminResponder_GetProvisionerPolicy(t *testing.T) {
ctx = acme.NewDatabaseContext(ctx, tc.acmeDB)
par := NewPolicyAdminResponder()
req := httptest.NewRequest("GET", "/foo", nil)
req := httptest.NewRequest("GET", "/foo", http.NoBody)
req = req.WithContext(ctx)
w := httptest.NewRecorder()
@ -1986,7 +1986,7 @@ func TestPolicyAdminResponder_GetACMEAccountPolicy(t *testing.T) {
ctx = acme.NewDatabaseContext(ctx, tc.acmeDB)
par := NewPolicyAdminResponder()
req := httptest.NewRequest("GET", "/foo", nil)
req := httptest.NewRequest("GET", "/foo", http.NoBody)
req = req.WithContext(ctx)
w := httptest.NewRecorder()

@ -4,7 +4,7 @@ import (
"fmt"
"net/http"
"github.com/go-chi/chi"
"github.com/go-chi/chi/v5"
"go.step.sm/crypto/sshutil"
"go.step.sm/crypto/x509util"
@ -38,21 +38,21 @@ func GetProvisioner(w http.ResponseWriter, r *http.Request) {
auth := mustAuthority(ctx)
db := admin.MustFromContext(ctx)
if len(id) > 0 {
if id != "" {
if p, err = auth.LoadProvisionerByID(id); err != nil {
render.Error(w, admin.WrapErrorISE(err, "error loading provisioner %s", id))
render.Error(w, r, admin.WrapErrorISE(err, "error loading provisioner %s", id))
return
}
} else {
if p, err = auth.LoadProvisionerByName(name); err != nil {
render.Error(w, admin.WrapErrorISE(err, "error loading provisioner %s", name))
render.Error(w, r, admin.WrapErrorISE(err, "error loading provisioner %s", name))
return
}
}
prov, err := db.GetProvisioner(ctx, p.GetID())
if err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
render.ProtoJSON(w, prov)
@ -62,17 +62,17 @@ func GetProvisioner(w http.ResponseWriter, r *http.Request) {
func GetProvisioners(w http.ResponseWriter, r *http.Request) {
cursor, limit, err := api.ParseCursor(r)
if err != nil {
render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err,
render.Error(w, r, admin.WrapError(admin.ErrorBadRequestType, err,
"error parsing cursor and limit from query params"))
return
}
p, next, err := mustAuthority(r.Context()).GetProvisioners(cursor, limit)
if err != nil {
render.Error(w, errs.InternalServerErr(err))
render.Error(w, r, errs.InternalServerErr(err))
return
}
render.JSON(w, &GetProvisionersResponse{
render.JSON(w, r, &GetProvisionersResponse{
Provisioners: p,
NextCursor: next,
})
@ -82,24 +82,24 @@ func GetProvisioners(w http.ResponseWriter, r *http.Request) {
func CreateProvisioner(w http.ResponseWriter, r *http.Request) {
var prov = new(linkedca.Provisioner)
if err := read.ProtoJSON(r.Body, prov); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
// TODO: Validate inputs
if err := authority.ValidateClaims(prov.Claims); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
// validate the templates and template data
if err := validateTemplates(prov.X509Template, prov.SshTemplate); err != nil {
render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err, "invalid template"))
render.Error(w, r, admin.WrapError(admin.ErrorBadRequestType, err, "invalid template"))
return
}
if err := mustAuthority(r.Context()).StoreProvisioner(r.Context(), prov); err != nil {
render.Error(w, admin.WrapErrorISE(err, "error storing provisioner %s", prov.Name))
render.Error(w, r, admin.WrapErrorISE(err, "error storing provisioner %s", prov.Name))
return
}
render.ProtoJSONStatus(w, prov, http.StatusCreated)
@ -116,31 +116,31 @@ func DeleteProvisioner(w http.ResponseWriter, r *http.Request) {
name := chi.URLParam(r, "name")
auth := mustAuthority(r.Context())
if len(id) > 0 {
if id != "" {
if p, err = auth.LoadProvisionerByID(id); err != nil {
render.Error(w, admin.WrapErrorISE(err, "error loading provisioner %s", id))
render.Error(w, r, admin.WrapErrorISE(err, "error loading provisioner %s", id))
return
}
} else {
if p, err = auth.LoadProvisionerByName(name); err != nil {
render.Error(w, admin.WrapErrorISE(err, "error loading provisioner %s", name))
render.Error(w, r, admin.WrapErrorISE(err, "error loading provisioner %s", name))
return
}
}
if err := auth.RemoveProvisioner(r.Context(), p.GetID()); err != nil {
render.Error(w, admin.WrapErrorISE(err, "error removing provisioner %s", p.GetName()))
render.Error(w, r, admin.WrapErrorISE(err, "error removing provisioner %s", p.GetName()))
return
}
render.JSON(w, &DeleteResponse{Status: "ok"})
render.JSON(w, r, &DeleteResponse{Status: "ok"})
}
// UpdateProvisioner updates an existing prov.
func UpdateProvisioner(w http.ResponseWriter, r *http.Request) {
var nu = new(linkedca.Provisioner)
if err := read.ProtoJSON(r.Body, nu); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
@ -151,51 +151,51 @@ func UpdateProvisioner(w http.ResponseWriter, r *http.Request) {
p, err := auth.LoadProvisionerByName(name)
if err != nil {
render.Error(w, admin.WrapErrorISE(err, "error loading provisioner from cached configuration '%s'", name))
render.Error(w, r, admin.WrapErrorISE(err, "error loading provisioner from cached configuration '%s'", name))
return
}
old, err := db.GetProvisioner(r.Context(), p.GetID())
if err != nil {
render.Error(w, admin.WrapErrorISE(err, "error loading provisioner from db '%s'", p.GetID()))
render.Error(w, r, admin.WrapErrorISE(err, "error loading provisioner from db '%s'", p.GetID()))
return
}
if nu.Id != old.Id {
render.Error(w, admin.NewErrorISE("cannot change provisioner ID"))
render.Error(w, r, admin.NewErrorISE("cannot change provisioner ID"))
return
}
if nu.Type != old.Type {
render.Error(w, admin.NewErrorISE("cannot change provisioner type"))
render.Error(w, r, admin.NewErrorISE("cannot change provisioner type"))
return
}
if nu.AuthorityId != old.AuthorityId {
render.Error(w, admin.NewErrorISE("cannot change provisioner authorityID"))
render.Error(w, r, admin.NewErrorISE("cannot change provisioner authorityID"))
return
}
if !nu.CreatedAt.AsTime().Equal(old.CreatedAt.AsTime()) {
render.Error(w, admin.NewErrorISE("cannot change provisioner createdAt"))
render.Error(w, r, admin.NewErrorISE("cannot change provisioner createdAt"))
return
}
if !nu.DeletedAt.AsTime().Equal(old.DeletedAt.AsTime()) {
render.Error(w, admin.NewErrorISE("cannot change provisioner deletedAt"))
render.Error(w, r, admin.NewErrorISE("cannot change provisioner deletedAt"))
return
}
// TODO: Validate inputs
if err := authority.ValidateClaims(nu.Claims); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
// validate the templates and template data
if err := validateTemplates(nu.X509Template, nu.SshTemplate); err != nil {
render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err, "invalid template"))
render.Error(w, r, admin.WrapError(admin.ErrorBadRequestType, err, "invalid template"))
return
}
if err := auth.UpdateProvisioner(r.Context(), nu); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
render.ProtoJSON(w, nu)

@ -12,7 +12,7 @@ import (
"testing"
"time"
"github.com/go-chi/chi"
"github.com/go-chi/chi/v5"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"google.golang.org/protobuf/encoding/protojson"
@ -37,7 +37,7 @@ func TestHandler_GetProvisioner(t *testing.T) {
}
var tests = map[string]func(t *testing.T) test{
"fail/auth.LoadProvisionerByID": func(t *testing.T) test {
req := httptest.NewRequest("GET", "/foo?id=provID", nil)
req := httptest.NewRequest("GET", "/foo?id=provID", http.NoBody)
chiCtx := chi.NewRouteContext()
ctx := context.WithValue(context.Background(), chi.RouteCtxKey, chiCtx)
auth := &mockAdminAuthority{
@ -61,7 +61,7 @@ func TestHandler_GetProvisioner(t *testing.T) {
}
},
"fail/auth.LoadProvisionerByName": func(t *testing.T) test {
req := httptest.NewRequest("GET", "/foo", nil)
req := httptest.NewRequest("GET", "/foo", http.NoBody)
chiCtx := chi.NewRouteContext()
chiCtx.URLParams.Add("name", "provName")
ctx := context.WithValue(context.Background(), chi.RouteCtxKey, chiCtx)
@ -86,7 +86,7 @@ func TestHandler_GetProvisioner(t *testing.T) {
}
},
"fail/db.GetProvisioner": func(t *testing.T) test {
req := httptest.NewRequest("GET", "/foo", nil)
req := httptest.NewRequest("GET", "/foo", http.NoBody)
chiCtx := chi.NewRouteContext()
chiCtx.URLParams.Add("name", "provName")
ctx := context.WithValue(context.Background(), chi.RouteCtxKey, chiCtx)
@ -120,7 +120,7 @@ func TestHandler_GetProvisioner(t *testing.T) {
}
},
"ok": func(t *testing.T) test {
req := httptest.NewRequest("GET", "/foo", nil)
req := httptest.NewRequest("GET", "/foo", http.NoBody)
chiCtx := chi.NewRouteContext()
chiCtx.URLParams.Add("name", "provName")
ctx := context.WithValue(context.Background(), chi.RouteCtxKey, chiCtx)
@ -208,7 +208,7 @@ func TestHandler_GetProvisioners(t *testing.T) {
}
var tests = map[string]func(t *testing.T) test{
"fail/parse-cursor": func(t *testing.T) test {
req := httptest.NewRequest("GET", "/foo?limit=X", nil)
req := httptest.NewRequest("GET", "/foo?limit=X", http.NoBody)
return test{
ctx: context.Background(),
statusCode: 400,
@ -222,7 +222,7 @@ func TestHandler_GetProvisioners(t *testing.T) {
}
},
"fail/auth.GetProvisioners": func(t *testing.T) test {
req := httptest.NewRequest("GET", "/foo", nil)
req := httptest.NewRequest("GET", "/foo", http.NoBody)
auth := &mockAdminAuthority{
MockGetProvisioners: func(cursor string, limit int) (provisioner.List, string, error) {
assert.Equals(t, "", cursor)
@ -244,7 +244,7 @@ func TestHandler_GetProvisioners(t *testing.T) {
}
},
"ok": func(t *testing.T) test {
req := httptest.NewRequest("GET", "/foo", nil)
req := httptest.NewRequest("GET", "/foo", http.NoBody)
provisioners := provisioner.List{
&provisioner.OIDC{
Type: "OIDC",
@ -481,7 +481,7 @@ func TestHandler_DeleteProvisioner(t *testing.T) {
}
var tests = map[string]func(t *testing.T) test{
"fail/auth.LoadProvisionerByID": func(t *testing.T) test {
req := httptest.NewRequest("DELETE", "/foo?id=provID", nil)
req := httptest.NewRequest("DELETE", "/foo?id=provID", http.NoBody)
chiCtx := chi.NewRouteContext()
ctx := context.WithValue(context.Background(), chi.RouteCtxKey, chiCtx)
auth := &mockAdminAuthority{
@ -504,7 +504,7 @@ func TestHandler_DeleteProvisioner(t *testing.T) {
}
},
"fail/auth.LoadProvisionerByName": func(t *testing.T) test {
req := httptest.NewRequest("DELETE", "/foo", nil)
req := httptest.NewRequest("DELETE", "/foo", http.NoBody)
chiCtx := chi.NewRouteContext()
chiCtx.URLParams.Add("name", "provName")
ctx := context.WithValue(context.Background(), chi.RouteCtxKey, chiCtx)
@ -528,7 +528,7 @@ func TestHandler_DeleteProvisioner(t *testing.T) {
}
},
"fail/auth.RemoveProvisioner": func(t *testing.T) test {
req := httptest.NewRequest("DELETE", "/foo", nil)
req := httptest.NewRequest("DELETE", "/foo", http.NoBody)
chiCtx := chi.NewRouteContext()
chiCtx.URLParams.Add("name", "provName")
ctx := context.WithValue(context.Background(), chi.RouteCtxKey, chiCtx)
@ -560,7 +560,7 @@ func TestHandler_DeleteProvisioner(t *testing.T) {
}
},
"ok": func(t *testing.T) test {
req := httptest.NewRequest("DELETE", "/foo", nil)
req := httptest.NewRequest("DELETE", "/foo", http.NoBody)
chiCtx := chi.NewRouteContext()
chiCtx.URLParams.Add("name", "provName")
ctx := context.WithValue(context.Background(), chi.RouteCtxKey, chiCtx)

@ -6,7 +6,7 @@ import (
"net/http"
"net/url"
"github.com/go-chi/chi"
"github.com/go-chi/chi/v5"
"github.com/smallstep/certificates/api/read"
"github.com/smallstep/certificates/api/render"
"github.com/smallstep/certificates/authority/admin"
@ -56,10 +56,8 @@ func validateWebhook(webhook *linkedca.Webhook) error {
}
// kind
switch webhook.Kind {
case linkedca.Webhook_ENRICHING, linkedca.Webhook_AUTHORIZING:
default:
return admin.NewError(admin.ErrorBadRequestType, "webhook kind is invalid")
if _, ok := linkedca.Webhook_Kind_name[int32(webhook.Kind)]; !ok || webhook.Kind == linkedca.Webhook_NO_KIND {
return admin.NewError(admin.ErrorBadRequestType, "webhook kind %q is invalid", webhook.Kind)
}
return nil
@ -73,28 +71,28 @@ func (war *webhookAdminResponder) CreateProvisionerWebhook(w http.ResponseWriter
var newWebhook = new(linkedca.Webhook)
if err := read.ProtoJSON(r.Body, newWebhook); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
if err := validateWebhook(newWebhook); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
if newWebhook.Secret != "" {
err := admin.NewError(admin.ErrorBadRequestType, "webhook secret must not be set")
render.Error(w, err)
render.Error(w, r, err)
return
}
if newWebhook.Id != "" {
err := admin.NewError(admin.ErrorBadRequestType, "webhook ID must not be set")
render.Error(w, err)
render.Error(w, r, err)
return
}
id, err := randutil.UUIDv4()
if err != nil {
render.Error(w, admin.WrapErrorISE(err, "error generating webhook id"))
render.Error(w, r, admin.WrapErrorISE(err, "error generating webhook id"))
return
}
newWebhook.Id = id
@ -103,14 +101,14 @@ func (war *webhookAdminResponder) CreateProvisionerWebhook(w http.ResponseWriter
for _, wh := range prov.Webhooks {
if wh.Name == newWebhook.Name {
err := admin.NewError(admin.ErrorConflictType, "provisioner %q already has a webhook with the name %q", prov.Name, newWebhook.Name)
render.Error(w, err)
render.Error(w, r, err)
return
}
}
secret, err := randutil.Bytes(64)
if err != nil {
render.Error(w, admin.WrapErrorISE(err, "error generating webhook secret"))
render.Error(w, r, admin.WrapErrorISE(err, "error generating webhook secret"))
return
}
newWebhook.Secret = base64.StdEncoding.EncodeToString(secret)
@ -119,11 +117,11 @@ func (war *webhookAdminResponder) CreateProvisionerWebhook(w http.ResponseWriter
if err := auth.UpdateProvisioner(ctx, prov); err != nil {
if isBadRequest(err) {
render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err, "error creating provisioner webhook"))
render.Error(w, r, admin.WrapError(admin.ErrorBadRequestType, err, "error creating provisioner webhook"))
return
}
render.Error(w, admin.WrapErrorISE(err, "error creating provisioner webhook"))
render.Error(w, r, admin.WrapErrorISE(err, "error creating provisioner webhook"))
return
}
@ -147,21 +145,21 @@ func (war *webhookAdminResponder) DeleteProvisionerWebhook(w http.ResponseWriter
}
}
if !found {
render.JSONStatus(w, DeleteResponse{Status: "ok"}, http.StatusOK)
render.JSONStatus(w, r, DeleteResponse{Status: "ok"}, http.StatusOK)
return
}
if err := auth.UpdateProvisioner(ctx, prov); err != nil {
if isBadRequest(err) {
render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err, "error deleting provisioner webhook"))
render.Error(w, r, admin.WrapError(admin.ErrorBadRequestType, err, "error deleting provisioner webhook"))
return
}
render.Error(w, admin.WrapErrorISE(err, "error deleting provisioner webhook"))
render.Error(w, r, admin.WrapErrorISE(err, "error deleting provisioner webhook"))
return
}
render.JSONStatus(w, DeleteResponse{Status: "ok"}, http.StatusOK)
render.JSONStatus(w, r, DeleteResponse{Status: "ok"}, http.StatusOK)
}
func (war *webhookAdminResponder) UpdateProvisionerWebhook(w http.ResponseWriter, r *http.Request) {
@ -172,12 +170,12 @@ func (war *webhookAdminResponder) UpdateProvisionerWebhook(w http.ResponseWriter
var newWebhook = new(linkedca.Webhook)
if err := read.ProtoJSON(r.Body, newWebhook); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
if err := validateWebhook(newWebhook); err != nil {
render.Error(w, err)
render.Error(w, r, err)
return
}
@ -188,13 +186,13 @@ func (war *webhookAdminResponder) UpdateProvisionerWebhook(w http.ResponseWriter
}
if newWebhook.Secret != "" && newWebhook.Secret != wh.Secret {
err := admin.NewError(admin.ErrorBadRequestType, "webhook secret cannot be updated")
render.Error(w, err)
render.Error(w, r, err)
return
}
newWebhook.Secret = wh.Secret
if newWebhook.Id != "" && newWebhook.Id != wh.Id {
err := admin.NewError(admin.ErrorBadRequestType, "webhook ID cannot be updated")
render.Error(w, err)
render.Error(w, r, err)
return
}
newWebhook.Id = wh.Id
@ -205,17 +203,17 @@ func (war *webhookAdminResponder) UpdateProvisionerWebhook(w http.ResponseWriter
if !found {
msg := fmt.Sprintf("provisioner %q has no webhook with the name %q", prov.Name, newWebhook.Name)
err := admin.NewError(admin.ErrorNotFoundType, msg)
render.Error(w, err)
render.Error(w, r, err)
return
}
if err := auth.UpdateProvisioner(ctx, prov); err != nil {
if isBadRequest(err) {
render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err, "error updating provisioner webhook"))
render.Error(w, r, admin.WrapError(admin.ErrorBadRequestType, err, "error updating provisioner webhook"))
return
}
render.Error(w, admin.WrapErrorISE(err, "error updating provisioner webhook"))
render.Error(w, r, admin.WrapErrorISE(err, "error updating provisioner webhook"))
return
}

@ -6,11 +6,12 @@ import (
"encoding/json"
"errors"
"io"
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/go-chi/chi"
"github.com/go-chi/chi/v5"
"github.com/smallstep/certificates/authority"
"github.com/smallstep/certificates/authority/admin"
"github.com/stretchr/testify/assert"
@ -180,6 +181,26 @@ func TestWebhookAdminResponder_CreateProvisionerWebhook(t *testing.T) {
statusCode: 400,
}
},
"fail/unsupported-webhook-kind": func(t *testing.T) test {
prov := &linkedca.Provisioner{
Name: "provName",
}
ctx := linkedca.NewContextWithProvisioner(context.Background(), prov)
adminErr := admin.NewError(admin.ErrorBadRequestType, `(line 5:13): invalid value for enum type: "UNSUPPORTED"`)
adminErr.Message = `(line 5:13): invalid value for enum type: "UNSUPPORTED"`
body := []byte(`
{
"name": "metadata",
"url": "https://example.com",
"kind": "UNSUPPORTED",
}`)
return test{
ctx: ctx,
body: body,
err: adminErr,
statusCode: 400,
}
},
"fail/auth.UpdateProvisioner-error": func(t *testing.T) test {
adm := &linkedca.Admin{
Subject: "step",
@ -355,7 +376,7 @@ func TestWebhookAdminResponder_DeleteProvisionerWebhook(t *testing.T) {
}
ctx = linkedca.NewContextWithProvisioner(ctx, prov)
ctx = admin.NewContext(ctx, &admin.MockDB{})
req := httptest.NewRequest("DELETE", "/foo", nil).WithContext(ctx)
req := httptest.NewRequest("DELETE", "/foo", http.NoBody).WithContext(ctx)
war := NewWebhookAdminResponder()

@ -92,11 +92,14 @@ func FromContext(ctx context.Context) (db DB, ok bool) {
// MustFromContext returns the current admin database from the given context. It
// will panic if it's not in the context.
func MustFromContext(ctx context.Context) DB {
if db, ok := FromContext(ctx); !ok {
var (
db DB
ok bool
)
if db, ok = FromContext(ctx); !ok {
panic("admin database is not in the context")
} else {
return db
}
return db
}
// MockDB is an implementation of the DB interface that should only be used as

@ -40,7 +40,7 @@ func (dba *dbAdmin) clone() *dbAdmin {
return &u
}
func (db *DB) getDBAdminBytes(ctx context.Context, id string) ([]byte, error) {
func (db *DB) getDBAdminBytes(_ context.Context, id string) ([]byte, error) {
data, err := db.db.Get(adminsTable, []byte(id))
if nosql.IsErrNotFound(err) {
return nil, admin.NewError(admin.ErrorNotFoundType, "admin %s not found", id)
@ -102,7 +102,7 @@ func (db *DB) GetAdmin(ctx context.Context, id string) (*linkedca.Admin, error)
// GetAdmins retrieves and unmarshals all active (not deleted) admins
// from the database.
// TODO should we be paginating?
func (db *DB) GetAdmins(ctx context.Context) ([]*linkedca.Admin, error) {
func (db *DB) GetAdmins(context.Context) ([]*linkedca.Admin, error) {
dbEntries, err := db.db.List(adminsTable)
if err != nil {
return nil, errors.Wrap(err, "error loading admins")
@ -115,12 +115,10 @@ func (db *DB) GetAdmins(ctx context.Context) ([]*linkedca.Admin, error) {
if errors.As(err, &ae) {
if ae.IsType(admin.ErrorDeletedType) || ae.IsType(admin.ErrorAuthorityMismatchType) {
continue
} else {
return nil, err
}
} else {
return nil, err
}
return nil, err
}
if adm.AuthorityId != db.authorityID {
continue

@ -857,7 +857,7 @@ func TestDB_CreateAdmin(t *testing.T) {
var _dba = new(dbAdmin)
assert.FatalError(t, json.Unmarshal(nu, _dba))
assert.True(t, len(_dba.ID) > 0 && _dba.ID == string(key))
assert.True(t, _dba.ID != "" && _dba.ID == string(key))
assert.Equals(t, _dba.AuthorityID, adm.AuthorityId)
assert.Equals(t, _dba.ProvisionerID, adm.ProvisionerId)
assert.Equals(t, _dba.Subject, adm.Subject)
@ -890,7 +890,7 @@ func TestDB_CreateAdmin(t *testing.T) {
var _dba = new(dbAdmin)
assert.FatalError(t, json.Unmarshal(nu, _dba))
assert.True(t, len(_dba.ID) > 0 && _dba.ID == string(key))
assert.True(t, _dba.ID != "" && _dba.ID == string(key))
assert.Equals(t, _dba.AuthorityID, adm.AuthorityId)
assert.Equals(t, _dba.ProvisionerID, adm.ProvisionerId)
assert.Equals(t, _dba.Subject, adm.Subject)

@ -36,7 +36,7 @@ func New(db nosqlDB.DB, authorityID string) (*DB, error) {
// save writes the new data to the database, overwriting the old data if it
// existed.
func (db *DB) save(ctx context.Context, id string, nu, old interface{}, typ string, table []byte) error {
func (db *DB) save(_ context.Context, id string, nu, old interface{}, typ string, table []byte) error {
var (
err error
newB []byte

@ -71,7 +71,7 @@ func (dbap *dbAuthorityPolicy) convert() *linkedca.Policy {
return dbToLinked(dbap.Policy)
}
func (db *DB) getDBAuthorityPolicyBytes(ctx context.Context, authorityID string) ([]byte, error) {
func (db *DB) getDBAuthorityPolicyBytes(_ context.Context, authorityID string) ([]byte, error) {
data, err := db.db.Get(authorityPoliciesTable, []byte(authorityID))
if nosql.IsErrNotFound(err) {
return nil, admin.NewError(admin.ErrorNotFoundType, "authority policy not found")

@ -70,7 +70,7 @@ func (dbp *dbProvisioner) convert2linkedca() (*linkedca.Provisioner, error) {
}, nil
}
func (db *DB) getDBProvisionerBytes(ctx context.Context, id string) ([]byte, error) {
func (db *DB) getDBProvisionerBytes(_ context.Context, id string) ([]byte, error) {
data, err := db.db.Get(provisionersTable, []byte(id))
if nosql.IsErrNotFound(err) {
return nil, admin.NewError(admin.ErrorNotFoundType, "provisioner %s not found", id)
@ -132,7 +132,7 @@ func (db *DB) GetProvisioner(ctx context.Context, id string) (*linkedca.Provisio
// GetProvisioners retrieves and unmarshals all active (not deleted) provisioners
// from the database.
func (db *DB) GetProvisioners(ctx context.Context) ([]*linkedca.Provisioner, error) {
func (db *DB) GetProvisioners(_ context.Context) ([]*linkedca.Provisioner, error) {
dbEntries, err := db.db.List(provisionersTable)
if err != nil {
return nil, errors.Wrap(err, "error loading provisioners")
@ -145,12 +145,10 @@ func (db *DB) GetProvisioners(ctx context.Context) ([]*linkedca.Provisioner, err
if errors.As(err, &ae) {
if ae.IsType(admin.ErrorDeletedType) || ae.IsType(admin.ErrorAuthorityMismatchType) {
continue
} else {
return nil, err
}
} else {
return nil, err
}
return nil, err
}
if prov.AuthorityId != db.authorityID {
continue

@ -906,7 +906,7 @@ func TestDB_CreateProvisioner(t *testing.T) {
var _dbp = new(dbProvisioner)
assert.FatalError(t, json.Unmarshal(nu, _dbp))
assert.True(t, len(_dbp.ID) > 0 && _dbp.ID == string(key))
assert.True(t, _dbp.ID != "" && _dbp.ID == string(key))
assert.Equals(t, _dbp.AuthorityID, prov.AuthorityId)
assert.Equals(t, _dbp.Type, prov.Type)
assert.Equals(t, _dbp.Name, prov.Name)
@ -944,7 +944,7 @@ func TestDB_CreateProvisioner(t *testing.T) {
var _dbp = new(dbProvisioner)
assert.FatalError(t, json.Unmarshal(nu, _dbp))
assert.True(t, len(_dbp.ID) > 0 && _dbp.ID == string(key))
assert.True(t, _dbp.ID != "" && _dbp.ID == string(key))
assert.Equals(t, _dbp.AuthorityID, prov.AuthorityId)
assert.Equals(t, _dbp.Type, prov.Type)
assert.Equals(t, _dbp.Name, prov.Name)
@ -1093,7 +1093,7 @@ func TestDB_UpdateProvisioner(t *testing.T) {
var _dbp = new(dbProvisioner)
assert.FatalError(t, json.Unmarshal(nu, _dbp))
assert.True(t, len(_dbp.ID) > 0 && _dbp.ID == string(key))
assert.True(t, _dbp.ID != "" && _dbp.ID == string(key))
assert.Equals(t, _dbp.AuthorityID, prov.AuthorityId)
assert.Equals(t, _dbp.Type, prov.Type)
assert.Equals(t, _dbp.Name, prov.Name)
@ -1188,7 +1188,7 @@ func TestDB_UpdateProvisioner(t *testing.T) {
var _dbp = new(dbProvisioner)
assert.FatalError(t, json.Unmarshal(nu, _dbp))
assert.True(t, len(_dbp.ID) > 0 && _dbp.ID == string(key))
assert.True(t, _dbp.ID != "" && _dbp.ID == string(key))
assert.Equals(t, _dbp.AuthorityID, prov.AuthorityId)
assert.Equals(t, _dbp.Type, prov.Type)
assert.Equals(t, _dbp.Name, prov.Name)

@ -205,8 +205,8 @@ func (e *Error) ToLog() (interface{}, error) {
}
// Render implements render.RenderableError for Error.
func (e *Error) Render(w http.ResponseWriter) {
func (e *Error) Render(w http.ResponseWriter, r *http.Request) {
e.Message = e.Err.Error()
render.JSONStatus(w, e, e.StatusCode())
render.JSONStatus(w, r, e, e.StatusCode())
}

@ -4,6 +4,7 @@ import (
"bytes"
"context"
"crypto"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/hex"
@ -61,7 +62,10 @@ type Authority struct {
x509Enforcers []provisioner.CertificateEnforcer
// SCEP CA
scepService *scep.Service
scepOptions *scep.Options
validateSCEP bool
scepAuthority *scep.Authority
scepKeyManager provisioner.SCEPKeyManager
// SSH CA
sshHostPassword []byte
@ -73,6 +77,11 @@ type Authority struct {
sshCAUserFederatedCerts []ssh.PublicKey
sshCAHostFederatedCerts []ssh.PublicKey
// CRL vars
crlTicker *time.Ticker
crlStopper chan struct{}
crlMutex sync.Mutex
// If true, do not re-initialize
initOnce bool
startTime time.Time
@ -96,6 +105,9 @@ type Authority struct {
// If true, do not output initialization logs
quietInit bool
// Called whenever applicable, in order to instrument the authority.
meter Meter
}
// Info contains information about the authority.
@ -117,6 +129,8 @@ func New(cfg *config.Config, opts ...Option) (*Authority, error) {
var a = &Authority{
config: cfg,
certificates: new(sync.Map),
validateSCEP: true,
meter: noopMeter{},
}
// Apply options.
@ -125,6 +139,9 @@ func New(cfg *config.Config, opts ...Option) (*Authority, error) {
return nil, err
}
}
if a.keyManager != nil {
a.keyManager = newInstrumentedKeyManager(a.keyManager, a.meter)
}
if !a.skipInit {
// Initialize authority from options or configuration.
@ -142,6 +159,7 @@ func NewEmbedded(opts ...Option) (*Authority, error) {
a := &Authority{
config: &config.Config{},
certificates: new(sync.Map),
meter: noopMeter{},
}
// Apply options.
@ -150,6 +168,9 @@ func NewEmbedded(opts ...Option) (*Authority, error) {
return nil, err
}
}
if a.keyManager != nil {
a.keyManager = newInstrumentedKeyManager(a.keyManager, a.meter)
}
// Validate required options
switch {
@ -192,11 +213,14 @@ func FromContext(ctx context.Context) (a *Authority, ok bool) {
// MustFromContext returns the current authority from the given context. It will
// panic if the authority is not in the context.
func MustFromContext(ctx context.Context) *Authority {
if a, ok := FromContext(ctx); !ok {
var (
a *Authority
ok bool
)
if a, ok = FromContext(ctx); !ok {
panic("authority is not in the context")
} else {
return a
}
return a
}
// ReloadAdminResources reloads admins and provisioners from the DB.
@ -256,6 +280,24 @@ func (a *Authority) ReloadAdminResources(ctx context.Context) error {
a.config.AuthorityConfig.Admins = adminList
a.admins = adminClxn
switch {
case a.requiresSCEP() && a.GetSCEP() == nil:
// TODO(hs): try to initialize SCEP here too? It's a bit
// problematic if this method is called as part of an update
// via Admin API and a password needs to be provided.
case a.requiresSCEP() && a.GetSCEP() != nil:
// update the SCEP Authority with the currently active SCEP
// provisioner names and revalidate the configuration.
a.scepAuthority.UpdateProvisioners(a.getSCEPProvisionerNames())
if err := a.scepAuthority.Validate(); err != nil {
log.Printf("failed validating SCEP authority: %v\n", err)
}
case !a.requiresSCEP() && a.GetSCEP() != nil:
// TODO(hs): don't remove the authority if we can't also
// reload it.
//a.scepAuthority = nil
}
return nil
}
@ -307,6 +349,8 @@ func (a *Authority) init() error {
if err != nil {
return err
}
a.keyManager = newInstrumentedKeyManager(a.keyManager, a.meter)
}
// Initialize linkedca client if necessary. On a linked RA, the issuer
@ -403,18 +447,19 @@ func (a *Authority) init() error {
return err
}
a.rootX509Certs = append(a.rootX509Certs, resp.RootCertificate)
a.intermediateX509Certs = append(a.intermediateX509Certs, resp.IntermediateCertificates...)
}
}
// Read root certificates and store them in the certificates map.
if len(a.rootX509Certs) == 0 {
a.rootX509Certs = make([]*x509.Certificate, len(a.config.Root))
for i, path := range a.config.Root {
crt, err := pemutil.ReadCertificate(path)
a.rootX509Certs = make([]*x509.Certificate, 0, len(a.config.Root))
for _, path := range a.config.Root {
crts, err := pemutil.ReadCertificateBundle(path)
if err != nil {
return err
}
a.rootX509Certs[i] = crt
a.rootX509Certs = append(a.rootX509Certs, crts...)
}
}
for _, crt := range a.rootX509Certs {
@ -429,13 +474,13 @@ func (a *Authority) init() error {
// Read federated certificates and store them in the certificates map.
if len(a.federatedX509Certs) == 0 {
a.federatedX509Certs = make([]*x509.Certificate, len(a.config.FederatedRoots))
for i, path := range a.config.FederatedRoots {
crt, err := pemutil.ReadCertificate(path)
a.federatedX509Certs = make([]*x509.Certificate, 0, len(a.config.FederatedRoots))
for _, path := range a.config.FederatedRoots {
crts, err := pemutil.ReadCertificateBundle(path)
if err != nil {
return err
}
a.federatedX509Certs[i] = crt
a.federatedX509Certs = append(a.federatedX509Certs, crts...)
}
}
for _, crt := range a.federatedX509Certs {
@ -540,50 +585,6 @@ func (a *Authority) init() error {
tmplVars.SSH.UserFederatedKeys = append(tmplVars.SSH.UserFederatedKeys, a.sshCAUserFederatedCerts...)
}
// Check if a KMS with decryption capability is required and available
if a.requiresDecrypter() {
if _, ok := a.keyManager.(kmsapi.Decrypter); !ok {
return errors.New("keymanager doesn't provide crypto.Decrypter")
}
}
// TODO: decide if this is a good approach for providing the SCEP functionality
// It currently mirrors the logic for the x509CAService
if a.requiresSCEPService() && a.scepService == nil {
var options scep.Options
// Read intermediate and create X509 signer and decrypter for default CAS.
options.CertificateChain, err = pemutil.ReadCertificateBundle(a.config.IntermediateCert)
if err != nil {
return err
}
options.CertificateChain = append(options.CertificateChain, a.rootX509Certs...)
options.Signer, err = a.keyManager.CreateSigner(&kmsapi.CreateSignerRequest{
SigningKey: a.config.IntermediateKey,
Password: a.password,
})
if err != nil {
return err
}
if km, ok := a.keyManager.(kmsapi.Decrypter); ok {
options.Decrypter, err = km.CreateDecrypter(&kmsapi.CreateDecrypterRequest{
DecryptionKey: a.config.IntermediateKey,
Password: a.password,
})
if err != nil {
return err
}
}
a.scepService, err = scep.NewService(ctx, options)
if err != nil {
return err
}
// TODO: mimick the x509CAService GetCertificateAuthority here too?
}
if a.config.AuthorityConfig.EnableAdmin {
// Initialize step-ca Admin Database if it's not already initialized using
// WithAdminDB.
@ -679,6 +680,95 @@ func (a *Authority) init() error {
return err
}
// The SCEP functionality is provided through an instance of
// scep.Authority. It is initialized when the CA is started and
// if it doesn't exist yet. It gets refreshed if it already
// exists. If the SCEP authority is no longer required on reload,
// it gets removed.
// TODO(hs): reloading through SIGHUP doesn't hit these cases. This
// is because an entirely new authority.Authority is created, including
// a new scep.Authority. Look into this to see if we want this to
// keep working like that, or want to reuse a single instance and
// update that.
switch {
case a.requiresSCEP() && a.GetSCEP() == nil:
if a.scepOptions == nil {
options := &scep.Options{
Roots: a.rootX509Certs,
Intermediates: a.intermediateX509Certs,
}
// intermediate certificates can be empty in RA mode
if len(a.intermediateX509Certs) > 0 {
options.SignerCert = a.intermediateX509Certs[0]
}
// attempt to create the (default) SCEP signer if the intermediate
// key is configured.
if a.config.IntermediateKey != "" {
if options.Signer, err = a.keyManager.CreateSigner(&kmsapi.CreateSignerRequest{
SigningKey: a.config.IntermediateKey,
Password: a.password,
}); err != nil {
return err
}
// TODO(hs): instead of creating the decrypter here, pass the
// intermediate key + chain down to the SCEP authority,
// and only instantiate it when required there. Is that possible?
// Also with entering passwords?
// TODO(hs): if moving the logic, try improving the logic for the
// decrypter password too? Right now it needs to be entered multiple
// times; I've observed it to be three times maximum, every time
// the intermediate key is read.
_, isRSAKey := options.Signer.Public().(*rsa.PublicKey)
if km, ok := a.keyManager.(kmsapi.Decrypter); ok && isRSAKey {
if decrypter, err := km.CreateDecrypter(&kmsapi.CreateDecrypterRequest{
DecryptionKey: a.config.IntermediateKey,
Password: a.password,
}); err == nil {
// only pass the decrypter down when it was successfully created,
// meaning it's an RSA key, and `CreateDecrypter` did not fail.
options.Decrypter = decrypter
options.DecrypterCert = options.Intermediates[0]
}
}
}
a.scepOptions = options
}
// provide the current SCEP provisioner names, so that the provisioners
// can be validated when the CA is started.
a.scepOptions.SCEPProvisionerNames = a.getSCEPProvisionerNames()
// create a new SCEP authority
scepAuthority, err := scep.New(a, *a.scepOptions)
if err != nil {
return err
}
if a.validateSCEP {
// validate the SCEP authority
if err := scepAuthority.Validate(); err != nil {
a.initLogf("failed validating SCEP authority: %v", err)
}
}
// set the SCEP authority
a.scepAuthority = scepAuthority
case !a.requiresSCEP() && a.GetSCEP() != nil:
// clear the SCEP authority if it's no longer required
a.scepAuthority = nil
case a.requiresSCEP() && a.GetSCEP() != nil:
// update the SCEP Authority with the currently active SCEP
// provisioner names and revalidate the configuration.
a.scepAuthority.UpdateProvisioners(a.getSCEPProvisionerNames())
if err := a.scepAuthority.Validate(); err != nil {
log.Printf("failed validating SCEP authority: %v\n", err)
}
}
// Load X509 constraints engine.
//
// This is currently only available in CA mode.
@ -711,6 +801,18 @@ func (a *Authority) init() error {
a.templates.Data["Step"] = tmplVars
}
// Start the CRL generator, we can assume the configuration is validated.
if a.config.CRL.IsEnabled() {
// Default cache duration to the default one
if v := a.config.CRL.CacheDuration; v == nil || v.Duration <= 0 {
a.config.CRL.CacheDuration = config.DefaultCRLCacheDuration
}
// Start CRL generator
if err := a.startCRLGenerator(); err != nil {
return err
}
}
// JWT numeric dates are seconds.
a.startTime = time.Now().Truncate(time.Second)
// Set flag indicating that initialization has been completed, and should
@ -777,6 +879,11 @@ func (a *Authority) IsAdminAPIEnabled() bool {
// Shutdown safely shuts down any clients, databases, etc. held by the Authority.
func (a *Authority) Shutdown() error {
if a.crlTicker != nil {
a.crlTicker.Stop()
close(a.crlStopper)
}
if err := a.keyManager.Close(); err != nil {
log.Printf("error closing the key manager: %v", err)
}
@ -785,6 +892,11 @@ func (a *Authority) Shutdown() error {
// CloseForReload closes internal services, to allow a safe reload.
func (a *Authority) CloseForReload() {
if a.crlTicker != nil {
a.crlTicker.Stop()
close(a.crlStopper)
}
if err := a.keyManager.Close(); err != nil {
log.Printf("error closing the key manager: %v", err)
}
@ -806,17 +918,9 @@ func (a *Authority) IsRevoked(sn string) (bool, error) {
return a.db.IsRevoked(sn)
}
// requiresDecrypter returns whether the Authority
// requires a KMS that provides a crypto.Decrypter
// Currently this is only required when SCEP is
// enabled.
func (a *Authority) requiresDecrypter() bool {
return a.requiresSCEPService()
}
// requiresSCEPService iterates over the configured provisioners
// and determines if one of them is a SCEP provisioner.
func (a *Authority) requiresSCEPService() bool {
// requiresSCEP iterates over the configured provisioners
// and determines if at least one of them is a SCEP provisioner.
func (a *Authority) requiresSCEP() bool {
for _, p := range a.config.AuthorityConfig.Provisioners {
if p.GetType() == provisioner.TypeSCEP {
return true
@ -825,11 +929,57 @@ func (a *Authority) requiresSCEPService() bool {
return false
}
// GetSCEPService returns the configured SCEP Service
// TODO: this function is intended to exist temporarily
// in order to make SCEP work more easily. It can be
// made more correct by using the right interfaces/abstractions
// after it works as expected.
func (a *Authority) GetSCEPService() *scep.Service {
return a.scepService
// getSCEPProvisionerNames returns the names of the SCEP provisioners
// that are currently available in the CA.
func (a *Authority) getSCEPProvisionerNames() (names []string) {
for _, p := range a.config.AuthorityConfig.Provisioners {
if p.GetType() == provisioner.TypeSCEP {
names = append(names, p.GetName())
}
}
return
}
// GetSCEP returns the configured SCEP Authority
func (a *Authority) GetSCEP() *scep.Authority {
return a.scepAuthority
}
func (a *Authority) startCRLGenerator() error {
if !a.config.CRL.IsEnabled() {
return nil
}
// Check that there is a valid CRL in the DB right now. If it doesn't exist
// or is expired, generate one now
_, ok := a.db.(db.CertificateRevocationListDB)
if !ok {
return errors.Errorf("CRL Generation requested, but database does not support CRL generation")
}
// Always create a new CRL on startup in case the CA has been down and the
// time to next expected CRL update is less than the cache duration.
if err := a.GenerateCertificateRevocationList(); err != nil {
return errors.Wrap(err, "could not generate a CRL")
}
a.crlStopper = make(chan struct{}, 1)
a.crlTicker = time.NewTicker(a.config.CRL.TickerDuration())
go func() {
for {
select {
case <-a.crlTicker.C:
log.Println("Regenerating CRL")
if err := a.GenerateCertificateRevocationList(); err != nil {
log.Printf("error regenerating the CRL: %v", err)
}
case <-a.crlStopper:
return
}
}
}()
return nil
}

@ -1,13 +1,16 @@
package authority
import (
"context"
"crypto"
"crypto/rand"
"crypto/sha256"
"crypto/x509"
"encoding/hex"
"encoding/pem"
"net"
"os"
"path/filepath"
"reflect"
"testing"
"time"
@ -18,6 +21,7 @@ import (
"github.com/smallstep/certificates/authority/provisioner"
"github.com/smallstep/certificates/db"
"go.step.sm/crypto/jose"
"go.step.sm/crypto/minica"
"go.step.sm/crypto/pemutil"
)
@ -109,7 +113,7 @@ func TestAuthorityNew(t *testing.T) {
c.Root = []string{"foo"}
return &newTest{
config: c,
err: errors.New("error reading foo: no such file or directory"),
err: errors.New(`error reading "foo": no such file or directory`),
}
},
"fail bad password": func(t *testing.T) *newTest {
@ -127,7 +131,7 @@ func TestAuthorityNew(t *testing.T) {
c.IntermediateCert = "wrong"
return &newTest{
config: c,
err: errors.New("error reading wrong: no such file or directory"),
err: errors.New(`error reading "wrong": no such file or directory`),
}
},
}
@ -172,6 +176,130 @@ func TestAuthorityNew(t *testing.T) {
}
}
func TestAuthorityNew_bundles(t *testing.T) {
ca0, err := minica.New()
if err != nil {
t.Fatal(err)
}
ca1, err := minica.New()
if err != nil {
t.Fatal(err)
}
ca2, err := minica.New()
if err != nil {
t.Fatal(err)
}
rootPath := t.TempDir()
writeCert := func(fn string, certs ...*x509.Certificate) error {
var b []byte
for _, crt := range certs {
b = append(b, pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE",
Bytes: crt.Raw,
})...)
}
return os.WriteFile(filepath.Join(rootPath, fn), b, 0600)
}
writeKey := func(fn string, signer crypto.Signer) error {
_, err := pemutil.Serialize(signer, pemutil.ToFile(filepath.Join(rootPath, fn), 0600))
return err
}
if err := writeCert("root0.crt", ca0.Root); err != nil {
t.Fatal(err)
}
if err := writeCert("int0.crt", ca0.Intermediate); err != nil {
t.Fatal(err)
}
if err := writeKey("int0.key", ca0.Signer); err != nil {
t.Fatal(err)
}
if err := writeCert("root1.crt", ca1.Root); err != nil {
t.Fatal(err)
}
if err := writeCert("int1.crt", ca1.Intermediate); err != nil {
t.Fatal(err)
}
if err := writeKey("int1.key", ca1.Signer); err != nil {
t.Fatal(err)
}
if err := writeCert("bundle0.crt", ca0.Root, ca1.Root); err != nil {
t.Fatal(err)
}
if err := writeCert("bundle1.crt", ca1.Root, ca2.Root); err != nil {
t.Fatal(err)
}
tests := []struct {
name string
config *config.Config
wantErr bool
}{
{"ok ca0", &config.Config{
Address: "127.0.0.1:443",
Root: []string{filepath.Join(rootPath, "root0.crt")},
IntermediateCert: filepath.Join(rootPath, "int0.crt"),
IntermediateKey: filepath.Join(rootPath, "int0.key"),
DNSNames: []string{"127.0.0.1"},
AuthorityConfig: &AuthConfig{},
}, false},
{"ok bundle", &config.Config{
Address: "127.0.0.1:443",
Root: []string{filepath.Join(rootPath, "bundle0.crt")},
IntermediateCert: filepath.Join(rootPath, "int0.crt"),
IntermediateKey: filepath.Join(rootPath, "int0.key"),
DNSNames: []string{"127.0.0.1"},
AuthorityConfig: &AuthConfig{},
}, false},
{"ok federated ca1", &config.Config{
Address: "127.0.0.1:443",
Root: []string{filepath.Join(rootPath, "root0.crt")},
FederatedRoots: []string{filepath.Join(rootPath, "root1.crt")},
IntermediateCert: filepath.Join(rootPath, "int0.crt"),
IntermediateKey: filepath.Join(rootPath, "int0.key"),
DNSNames: []string{"127.0.0.1"},
AuthorityConfig: &AuthConfig{},
}, false},
{"ok federated bundle", &config.Config{
Address: "127.0.0.1:443",
Root: []string{filepath.Join(rootPath, "root0.crt")},
FederatedRoots: []string{filepath.Join(rootPath, "bundle1.crt")},
IntermediateCert: filepath.Join(rootPath, "int0.crt"),
IntermediateKey: filepath.Join(rootPath, "int0.key"),
DNSNames: []string{"127.0.0.1"},
AuthorityConfig: &AuthConfig{},
}, false},
{"fail root", &config.Config{
Address: "127.0.0.1:443",
Root: []string{filepath.Join(rootPath, "missing.crt")},
IntermediateCert: filepath.Join(rootPath, "int0.crt"),
IntermediateKey: filepath.Join(rootPath, "int0.key"),
DNSNames: []string{"127.0.0.1"},
AuthorityConfig: &AuthConfig{},
}, true},
{"fail federated", &config.Config{
Address: "127.0.0.1:443",
Root: []string{filepath.Join(rootPath, "root0.crt")},
FederatedRoots: []string{filepath.Join(rootPath, "missing.crt")},
IntermediateCert: filepath.Join(rootPath, "int0.crt"),
IntermediateKey: filepath.Join(rootPath, "int0.key"),
DNSNames: []string{"127.0.0.1"},
AuthorityConfig: &AuthConfig{},
}, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := New(tt.config)
if (err != nil) != tt.wantErr {
t.Errorf("New() error = %v, wantErr %v", err, tt.wantErr)
return
}
})
}
}
func TestAuthority_GetDatabase(t *testing.T) {
auth := testAuthority(t)
authWithDatabase, err := New(auth.config, WithDatabase(auth.db))
@ -287,7 +415,7 @@ func TestNewEmbedded_Sign(t *testing.T) {
csr, err := x509.ParseCertificateRequest(cr)
assert.FatalError(t, err)
cert, err := a.Sign(csr, provisioner.SignOptions{})
cert, err := a.SignWithContext(context.Background(), csr, provisioner.SignOptions{})
assert.FatalError(t, err)
assert.Equals(t, []string{"foo.bar.zar"}, cert[0].DNSNames)
assert.Equals(t, crt, cert[1])
@ -351,7 +479,7 @@ func testScepAuthority(t *testing.T, opts ...Option) *Authority {
return a
}
func TestAuthority_GetSCEPService(t *testing.T) {
func TestAuthority_GetSCEP(t *testing.T) {
_ = testScepAuthority(t)
p := provisioner.List{
&provisioner.SCEP{
@ -415,7 +543,7 @@ func TestAuthority_GetSCEPService(t *testing.T) {
return
}
if tt.wantService {
if got := a.GetSCEPService(); (got != nil) != tt.wantService {
if got := a.GetSCEP(); (got != nil) != tt.wantService {
t.Errorf("Authority.GetSCEPService() = %v, wantService %v", got, tt.wantService)
}
}

@ -177,7 +177,7 @@ func (a *Authority) AuthorizeAdminToken(r *http.Request, token string) (*linkedc
if !adminFound {
return nil, admin.NewError(admin.ErrorUnauthorizedType,
"adminHandler.authorizeToken; unable to load admin with subject(s) %s and provisioner '%s'",
adminSANs, claims.Issuer)
adminSANs, prov.GetName())
}
if strings.HasPrefix(r.URL.Path, "/admin/admins") && (r.Method != "GET") && adm.Type != linkedca.Admin_SUPER_ADMIN {
@ -214,7 +214,7 @@ func (a *Authority) Authorize(ctx context.Context, token string) ([]provisioner.
var opts = []interface{}{errs.WithKeyVal("token", token)}
switch m := provisioner.MethodFromContext(ctx); m {
case provisioner.SignMethod:
case provisioner.SignMethod, provisioner.SignIdentityMethod:
signOpts, err := a.authorizeSign(ctx, token)
return signOpts, errs.Wrap(http.StatusInternalServerError, err, "authority.Authorize", opts...)
case provisioner.RevokeMethod:
@ -286,16 +286,16 @@ func (a *Authority) authorizeRevoke(ctx context.Context, token string) error {
// extra extension cannot be found, authorize the renewal by default.
//
// TODO(mariano): should we authorize by default?
func (a *Authority) authorizeRenew(cert *x509.Certificate) error {
func (a *Authority) authorizeRenew(ctx context.Context, cert *x509.Certificate) (provisioner.Interface, error) {
serial := cert.SerialNumber.String()
var opts = []interface{}{errs.WithKeyVal("serialNumber", serial)}
isRevoked, err := a.IsRevoked(serial)
if err != nil {
return errs.Wrap(http.StatusInternalServerError, err, "authority.authorizeRenew", opts...)
return nil, errs.Wrap(http.StatusInternalServerError, err, "authority.authorizeRenew", opts...)
}
if isRevoked {
return errs.Unauthorized("authority.authorizeRenew: certificate has been revoked", opts...)
return nil, errs.Unauthorized("authority.authorizeRenew: certificate has been revoked", opts...)
}
p, err := a.LoadProvisionerByCertificate(cert)
if err != nil {
@ -305,17 +305,17 @@ func (a *Authority) authorizeRenew(cert *x509.Certificate) error {
// returns the noop provisioner if this happens, and it allows
// certificate renewals.
if p, ok = a.provisioners.LoadByCertificate(cert); !ok {
return errs.Unauthorized("authority.authorizeRenew: provisioner not found", opts...)
return nil, errs.Unauthorized("authority.authorizeRenew: provisioner not found", opts...)
}
}
if err := p.AuthorizeRenew(context.Background(), cert); err != nil {
return errs.Wrap(http.StatusInternalServerError, err, "authority.authorizeRenew", opts...)
if err := p.AuthorizeRenew(ctx, cert); err != nil {
return nil, errs.Wrap(http.StatusInternalServerError, err, "authority.authorizeRenew", opts...)
}
return nil
return p, nil
}
// authorizeSSHCertificate returns an error if the given certificate is revoked.
func (a *Authority) authorizeSSHCertificate(ctx context.Context, cert *ssh.Certificate) error {
func (a *Authority) authorizeSSHCertificate(_ context.Context, cert *ssh.Certificate) error {
var err error
var isRevoked bool
@ -394,7 +394,7 @@ func (a *Authority) authorizeSSHRevoke(ctx context.Context, token string) error
// AuthorizeRenewToken validates the renew token and returns the leaf
// certificate in the x5cInsecure header.
func (a *Authority) AuthorizeRenewToken(ctx context.Context, ott string) (*x509.Certificate, error) {
func (a *Authority) AuthorizeRenewToken(_ context.Context, ott string) (*x509.Certificate, error) {
var claims jose.Claims
jwt, chain, err := jose.ParseX5cInsecure(ott, a.rootX509Certs)
if err != nil {
@ -434,7 +434,7 @@ func (a *Authority) AuthorizeRenewToken(ctx context.Context, ott string) (*x509.
}
audiences := a.config.GetAudiences().Renew
if !matchesAudience(claims.Audience, audiences) {
if !matchesAudience(claims.Audience, audiences) && !isRAProvisioner(p) {
return nil, errs.InternalServerErr(jose.ErrInvalidAudience, errs.WithMessage("error validating renew token: invalid audience claim (aud)"))
}

@ -876,7 +876,7 @@ func TestAuthority_authorizeRenew(t *testing.T) {
t.Run(name, func(t *testing.T) {
tc := genTestCase(t)
err := tc.auth.authorizeRenew(tc.cert)
_, err := tc.auth.authorizeRenew(context.Background(), tc.cert)
if err != nil {
if assert.NotNil(t, tc.err) {
var sc render.StatusCodedError
@ -1375,7 +1375,7 @@ func TestAuthority_AuthorizeRenewToken(t *testing.T) {
}
generateX5cToken := func(a *Authority, key crypto.Signer, claims jose.Claims, opts ...provisioner.SignOption) (string, *x509.Certificate) {
chain, err := a.Sign(csr, provisioner.SignOptions{}, opts...)
chain, err := a.SignWithContext(ctx, csr, provisioner.SignOptions{}, opts...)
if err != nil {
t.Fatal(err)
}
@ -1459,6 +1459,37 @@ func TestAuthority_AuthorizeRenewToken(t *testing.T) {
})
return nil
}))
a4 := testAuthority(t)
a4.db = &db.MockAuthDB{
MUseToken: func(id, tok string) (bool, error) {
return true, nil
},
MGetCertificateData: func(serialNumber string) (*db.CertificateData, error) {
return &db.CertificateData{
Provisioner: &db.ProvisionerData{ID: "Max:IMi94WBNI6gP5cNHXlZYNUzvMjGdHyBRmFoo-lCEaqk", Name: "Max"},
RaInfo: &provisioner.RAInfo{ProvisionerName: "ra"},
}, nil
},
}
t4, c4 := generateX5cToken(a1, signer, jose.Claims{
Audience: []string{"https://ra.example.com/1.0/renew"},
Subject: "test.example.com",
Issuer: "step-ca-client/1.0",
NotBefore: jose.NewNumericDate(now),
Expiry: jose.NewNumericDate(now.Add(5 * time.Minute)),
}, provisioner.CertificateEnforcerFunc(func(cert *x509.Certificate) error {
cert.NotBefore = now
cert.NotAfter = now.Add(time.Hour)
b, err := asn1.Marshal(stepProvisionerASN1{int(provisioner.TypeJWK), []byte("step-cli"), nil, nil})
if err != nil {
return err
}
cert.ExtraExtensions = append(cert.ExtraExtensions, pkix.Extension{
Id: asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 37476, 9000, 64, 1},
Value: b,
})
return nil
}))
badSigner, _ := generateX5cToken(a1, otherSigner, jose.Claims{
Audience: []string{"https://example.com/1.0/renew"},
Subject: "test.example.com",
@ -1627,6 +1658,7 @@ func TestAuthority_AuthorizeRenewToken(t *testing.T) {
{"ok", a1, args{ctx, t1}, c1, false},
{"ok expired cert", a1, args{ctx, t2}, c2, false},
{"ok provisioner issuer", a1, args{ctx, t3}, c3, false},
{"ok ra provisioner", a4, args{ctx, t4}, c4, false},
{"fail token", a1, args{ctx, "not.a.token"}, nil, true},
{"fail token reuse", a1, args{ctx, t1}, nil, true},
{"fail token signature", a1, args{ctx, badSigner}, nil, true},

@ -1,6 +1,7 @@
package config
import (
"bytes"
"encoding/json"
"fmt"
"net"
@ -35,21 +36,30 @@ var (
// DefaultEnableSSHCA enable SSH CA features per provisioner or globally
// for all provisioners.
DefaultEnableSSHCA = false
// GlobalProvisionerClaims default claims for the Authority. Can be overridden
// by provisioner specific claims.
// DefaultDisableSmallstepExtensions is the default value for the
// DisableSmallstepExtensions provisioner claim.
DefaultDisableSmallstepExtensions = false
// DefaultCRLCacheDuration is the default cache duration for the CRL.
DefaultCRLCacheDuration = &provisioner.Duration{Duration: 24 * time.Hour}
// DefaultCRLExpiredDuration is the default duration in which expired
// certificates will remain in the CRL after expiration.
DefaultCRLExpiredDuration = time.Hour
// GlobalProvisionerClaims is the default duration that expired certificates
// remain in the CRL after expiration.
GlobalProvisionerClaims = provisioner.Claims{
MinTLSDur: &provisioner.Duration{Duration: 5 * time.Minute}, // TLS certs
MaxTLSDur: &provisioner.Duration{Duration: 24 * time.Hour},
DefaultTLSDur: &provisioner.Duration{Duration: 24 * time.Hour},
MinUserSSHDur: &provisioner.Duration{Duration: 5 * time.Minute}, // User SSH certs
MaxUserSSHDur: &provisioner.Duration{Duration: 24 * time.Hour},
DefaultUserSSHDur: &provisioner.Duration{Duration: 16 * time.Hour},
MinHostSSHDur: &provisioner.Duration{Duration: 5 * time.Minute}, // Host SSH certs
MaxHostSSHDur: &provisioner.Duration{Duration: 30 * 24 * time.Hour},
DefaultHostSSHDur: &provisioner.Duration{Duration: 30 * 24 * time.Hour},
EnableSSHCA: &DefaultEnableSSHCA,
DisableRenewal: &DefaultDisableRenewal,
AllowRenewalAfterExpiry: &DefaultAllowRenewalAfterExpiry,
MinTLSDur: &provisioner.Duration{Duration: 5 * time.Minute}, // TLS certs
MaxTLSDur: &provisioner.Duration{Duration: 24 * time.Hour},
DefaultTLSDur: &provisioner.Duration{Duration: 24 * time.Hour},
MinUserSSHDur: &provisioner.Duration{Duration: 5 * time.Minute}, // User SSH certs
MaxUserSSHDur: &provisioner.Duration{Duration: 24 * time.Hour},
DefaultUserSSHDur: &provisioner.Duration{Duration: 16 * time.Hour},
MinHostSSHDur: &provisioner.Duration{Duration: 5 * time.Minute}, // Host SSH certs
MaxHostSSHDur: &provisioner.Duration{Duration: 30 * 24 * time.Hour},
DefaultHostSSHDur: &provisioner.Duration{Duration: 30 * 24 * time.Hour},
EnableSSHCA: &DefaultEnableSSHCA,
DisableRenewal: &DefaultDisableRenewal,
AllowRenewalAfterExpiry: &DefaultAllowRenewalAfterExpiry,
DisableSmallstepExtensions: &DefaultDisableSmallstepExtensions,
}
)
@ -72,12 +82,64 @@ type Config struct {
Password string `json:"password,omitempty"`
Templates *templates.Templates `json:"templates,omitempty"`
CommonName string `json:"commonName,omitempty"`
CRL *CRLConfig `json:"crl,omitempty"`
MetricsAddress string `json:"metricsAddress,omitempty"`
SkipValidation bool `json:"-"`
// Keeps record of the filename the Config is read from
loadedFromFilepath string
}
// CRLConfig represents config options for CRL generation
type CRLConfig struct {
Enabled bool `json:"enabled"`
GenerateOnRevoke bool `json:"generateOnRevoke,omitempty"`
CacheDuration *provisioner.Duration `json:"cacheDuration,omitempty"`
RenewPeriod *provisioner.Duration `json:"renewPeriod,omitempty"`
IDPurl string `json:"idpURL,omitempty"`
}
// IsEnabled returns if the CRL is enabled.
func (c *CRLConfig) IsEnabled() bool {
return c != nil && c.Enabled
}
// Validate validates the CRL configuration.
func (c *CRLConfig) Validate() error {
if c == nil {
return nil
}
if c.CacheDuration != nil && c.CacheDuration.Duration < 0 {
return errors.New("crl.cacheDuration must be greater than or equal to 0")
}
if c.RenewPeriod != nil && c.RenewPeriod.Duration < 0 {
return errors.New("crl.renewPeriod must be greater than or equal to 0")
}
if c.RenewPeriod != nil && c.CacheDuration != nil &&
c.RenewPeriod.Duration > c.CacheDuration.Duration {
return errors.New("crl.cacheDuration must be greater than or equal to crl.renewPeriod")
}
return nil
}
// TickerDuration the renewal ticker duration. This is set by renewPeriod, of it
// is not set is ~2/3 of cacheDuration.
func (c *CRLConfig) TickerDuration() time.Duration {
if !c.IsEnabled() {
return 0
}
if c.RenewPeriod != nil && c.RenewPeriod.Duration > 0 {
return c.RenewPeriod.Duration
}
return (c.CacheDuration.Duration / 3) * 2
}
// ASN1DN contains ASN1.DN attributes that are used in Subject and Issuer
// x509 Certificate blocks.
type ASN1DN struct {
@ -126,7 +188,7 @@ func (c *AuthConfig) init() {
}
// Validate validates the authority configuration.
func (c *AuthConfig) Validate(audiences provisioner.Audiences) error {
func (c *AuthConfig) Validate(provisioner.Audiences) error {
if c == nil {
return errors.New("authority cannot be undefined")
}
@ -190,20 +252,24 @@ func (c *Config) Init() {
if c.CommonName == "" {
c.CommonName = "Step Online CA"
}
if c.CRL != nil && c.CRL.Enabled && c.CRL.CacheDuration == nil {
c.CRL.CacheDuration = DefaultCRLCacheDuration
}
c.AuthorityConfig.init()
}
// Save saves the configuration to the given filename.
func (c *Config) Save(filename string) error {
f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
return errors.Wrapf(err, "error opening %s", filename)
}
defer f.Close()
enc := json.NewEncoder(f)
var b bytes.Buffer
enc := json.NewEncoder(&b)
enc.SetIndent("", "\t")
return errors.Wrapf(enc.Encode(c), "error writing %s", filename)
if err := enc.Encode(c); err != nil {
return fmt.Errorf("error encoding configuration: %w", err)
}
if err := os.WriteFile(filename, b.Bytes(), 0600); err != nil {
return fmt.Errorf("error writing %q: %w", filename, err)
}
return nil
}
// Commit saves the current configuration to the same
@ -262,6 +328,12 @@ func (c *Config) Validate() error {
return errors.Errorf("invalid address %s", c.Address)
}
if addr := c.MetricsAddress; addr != "" {
if _, _, err := net.SplitHostPort(addr); err != nil {
return errors.Errorf("invalid metrics address %q", c.Address)
}
}
if c.TLS == nil {
c.TLS = &DefaultTLSOptions
} else {
@ -300,6 +372,11 @@ func (c *Config) Validate() error {
return err
}
// Validate crl config: nil is ok
if err := c.CRL.Validate(); err != nil {
return err
}
return c.AuthorityConfig.Validate(c.GetAudiences())
}

@ -203,7 +203,7 @@ func matchURIConstraint(uri *url.URL, constraint string) (bool, error) {
// domainToReverseLabels converts a textual domain name like foo.example.com to
// the list of labels in reverse order, e.g. ["com", "example", "foo"].
func domainToReverseLabels(domain string) (reverseLabels []string, ok bool) {
for len(domain) > 0 {
for domain != "" {
if i := strings.LastIndexByte(domain, '.'); i == -1 {
reverseLabels = append(reverseLabels, domain)
domain = ""
@ -316,7 +316,7 @@ func parseRFC2821Mailbox(in string) (mailbox rfc2821Mailbox, ok bool) {
} else {
// Atom ("." Atom)*
NextChar:
for len(in) > 0 {
for in != "" {
// atext from RFC 2822, Section 3.2.4
c := in[0]

@ -110,7 +110,7 @@ func newLinkedCAClient(token string) (*linkedCaClient, error) {
tlsConfig.GetClientCertificate = renewer.GetClientCertificate
// Start mTLS client
conn, err := grpc.Dial(u.Host, grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)))
conn, err := grpc.NewClient(u.Host, grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)))
if err != nil {
return nil, errors.Wrapf(err, "error connecting %s", u.Host)
}
@ -265,8 +265,20 @@ func (c *linkedCaClient) GetCertificateData(serial string) (*db.CertificateData,
ID: p.Id, Name: p.Name, Type: p.Type.String(),
}
}
var raInfo *provisioner.RAInfo
if p := resp.RaProvisioner; p != nil && p.Provisioner != nil {
raInfo = &provisioner.RAInfo{
AuthorityID: p.AuthorityId,
ProvisionerID: p.Provisioner.Id,
ProvisionerType: p.Provisioner.Type.String(),
ProvisionerName: p.Provisioner.Name,
}
}
return &db.CertificateData{
Provisioner: pd,
RaInfo: raInfo,
}, nil
}
@ -369,19 +381,19 @@ func (c *linkedCaClient) IsSSHRevoked(serial string) (bool, error) {
return resp.Status != linkedca.RevocationStatus_ACTIVE, nil
}
func (c *linkedCaClient) CreateAuthorityPolicy(ctx context.Context, policy *linkedca.Policy) error {
func (c *linkedCaClient) CreateAuthorityPolicy(_ context.Context, _ *linkedca.Policy) error {
return errors.New("not implemented yet")
}
func (c *linkedCaClient) GetAuthorityPolicy(ctx context.Context) (*linkedca.Policy, error) {
func (c *linkedCaClient) GetAuthorityPolicy(context.Context) (*linkedca.Policy, error) {
return nil, errors.New("not implemented yet")
}
func (c *linkedCaClient) UpdateAuthorityPolicy(ctx context.Context, policy *linkedca.Policy) error {
func (c *linkedCaClient) UpdateAuthorityPolicy(_ context.Context, _ *linkedca.Policy) error {
return errors.New("not implemented yet")
}
func (c *linkedCaClient) DeleteAuthorityPolicy(ctx context.Context) error {
func (c *linkedCaClient) DeleteAuthorityPolicy(context.Context) error {
return errors.New("not implemented yet")
}
@ -466,10 +478,7 @@ func getAuthority(sans []string) (string, error) {
// getRootCertificate creates an insecure majordomo client and returns the
// verified root certificate.
func getRootCertificate(endpoint, fingerprint string) (*x509.Certificate, error) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
conn, err := grpc.DialContext(ctx, endpoint, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{
conn, err := grpc.NewClient(endpoint, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{
//nolint:gosec // used in bootstrap protocol
InsecureSkipVerify: true, // lgtm[go/disabled-certificate-check]
})))
@ -477,7 +486,7 @@ func getRootCertificate(endpoint, fingerprint string) (*x509.Certificate, error)
return nil, errors.Wrapf(err, "error connecting %s", endpoint)
}
ctx, cancel = context.WithTimeout(context.Background(), 15*time.Second)
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
client := linkedca.NewMajordomoClient(conn)
@ -519,11 +528,7 @@ func getRootCertificate(endpoint, fingerprint string) (*x509.Certificate, error)
// login creates a new majordomo client with just the root ca pool and returns
// the signed certificate and tls configuration.
func login(authority, token string, csr *x509.CertificateRequest, signer crypto.PrivateKey, endpoint string, rootCAs *x509.CertPool) (*tls.Certificate, *tls.Config, error) {
// Connect to majordomo
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
conn, err := grpc.DialContext(ctx, endpoint, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{
conn, err := grpc.NewClient(endpoint, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{
MinVersion: tls.VersionTLS12,
RootCAs: rootCAs,
})))
@ -532,7 +537,7 @@ func login(authority, token string, csr *x509.CertificateRequest, signer crypto.
}
// Login to get the signed certificate
ctx, cancel = context.WithTimeout(context.Background(), 15*time.Second)
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
client := linkedca.NewMajordomoClient(conn)

@ -0,0 +1,111 @@
package authority
import (
"crypto"
"io"
"go.step.sm/crypto/kms"
kmsapi "go.step.sm/crypto/kms/apiv1"
"github.com/smallstep/certificates/authority/provisioner"
)
// Meter wraps the set of defined callbacks for metrics gatherers.
type Meter interface {
// X509Signed is called whenever an X509 certificate is signed.
X509Signed(provisioner.Interface, error)
// X509Renewed is called whenever an X509 certificate is renewed.
X509Renewed(provisioner.Interface, error)
// X509Rekeyed is called whenever an X509 certificate is rekeyed.
X509Rekeyed(provisioner.Interface, error)
// X509WebhookAuthorized is called whenever an X509 authoring webhook is called.
X509WebhookAuthorized(provisioner.Interface, error)
// X509WebhookEnriched is called whenever an X509 enriching webhook is called.
X509WebhookEnriched(provisioner.Interface, error)
// SSHSigned is called whenever an SSH certificate is signed.
SSHSigned(provisioner.Interface, error)
// SSHRenewed is called whenever an SSH certificate is renewed.
SSHRenewed(provisioner.Interface, error)
// SSHRekeyed is called whenever an SSH certificate is rekeyed.
SSHRekeyed(provisioner.Interface, error)
// SSHWebhookAuthorized is called whenever an SSH authoring webhook is called.
SSHWebhookAuthorized(provisioner.Interface, error)
// SSHWebhookEnriched is called whenever an SSH enriching webhook is called.
SSHWebhookEnriched(provisioner.Interface, error)
// KMSSigned is called per KMS signer signature.
KMSSigned(error)
}
// noopMeter implements a noop [Meter].
type noopMeter struct{}
func (noopMeter) SSHRekeyed(provisioner.Interface, error) {}
func (noopMeter) SSHRenewed(provisioner.Interface, error) {}
func (noopMeter) SSHSigned(provisioner.Interface, error) {}
func (noopMeter) SSHWebhookAuthorized(provisioner.Interface, error) {}
func (noopMeter) SSHWebhookEnriched(provisioner.Interface, error) {}
func (noopMeter) X509Rekeyed(provisioner.Interface, error) {}
func (noopMeter) X509Renewed(provisioner.Interface, error) {}
func (noopMeter) X509Signed(provisioner.Interface, error) {}
func (noopMeter) X509WebhookAuthorized(provisioner.Interface, error) {}
func (noopMeter) X509WebhookEnriched(provisioner.Interface, error) {}
func (noopMeter) KMSSigned(error) {}
type instrumentedKeyManager struct {
kms.KeyManager
meter Meter
}
type instrumentedKeyAndDecrypterManager struct {
kms.KeyManager
decrypter kmsapi.Decrypter
meter Meter
}
func newInstrumentedKeyManager(k kms.KeyManager, m Meter) kms.KeyManager {
decrypter, isDecrypter := k.(kmsapi.Decrypter)
switch {
case isDecrypter:
return &instrumentedKeyAndDecrypterManager{&instrumentedKeyManager{k, m}, decrypter, m}
default:
return &instrumentedKeyManager{k, m}
}
}
func (i *instrumentedKeyManager) CreateSigner(req *kmsapi.CreateSignerRequest) (s crypto.Signer, err error) {
if s, err = i.KeyManager.CreateSigner(req); err == nil {
s = &instrumentedKMSSigner{s, i.meter}
}
return
}
func (i *instrumentedKeyAndDecrypterManager) CreateDecrypter(req *kmsapi.CreateDecrypterRequest) (s crypto.Decrypter, err error) {
return i.decrypter.CreateDecrypter(req)
}
type instrumentedKMSSigner struct {
crypto.Signer
meter Meter
}
func (i *instrumentedKMSSigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) {
signature, err = i.Signer.Sign(rand, digest, opts)
i.meter.KMSSigned(err)
return
}
var _ kms.KeyManager = (*instrumentedKeyManager)(nil)
var _ kms.KeyManager = (*instrumentedKeyAndDecrypterManager)(nil)
var _ kmsapi.Decrypter = (*instrumentedKeyAndDecrypterManager)(nil)

@ -18,6 +18,7 @@ import (
"github.com/smallstep/certificates/cas"
casapi "github.com/smallstep/certificates/cas/apiv1"
"github.com/smallstep/certificates/db"
"github.com/smallstep/certificates/scep"
)
// Option sets options to the Authority.
@ -166,6 +167,15 @@ func WithKeyManager(k kms.KeyManager) Option {
}
}
// WithX509CAService allows the consumer to provide an externally implemented
// API implementation of apiv1.CertificateAuthorityService
func WithX509CAService(svc casapi.CertificateAuthorityService) Option {
return func(a *Authority) error {
a.x509CAService = svc
return nil
}
}
// WithX509Signer defines the signer used to sign X509 certificates.
func WithX509Signer(crt *x509.Certificate, s crypto.Signer) Option {
return WithX509SignerChain([]*x509.Certificate{crt}, s)
@ -205,6 +215,27 @@ func WithX509SignerFunc(fn func() ([]*x509.Certificate, crypto.Signer, error)) O
}
}
// WithFullSCEPOptions defines the options used for SCEP support.
//
// This feature is EXPERIMENTAL and might change at any time.
func WithFullSCEPOptions(options *scep.Options) Option {
return func(a *Authority) error {
a.scepOptions = options
a.validateSCEP = false
return nil
}
}
// WithSCEPKeyManager defines the key manager used on SCEP provisioners.
//
// This feature is EXPERIMENTAL and might change at any time.
func WithSCEPKeyManager(skm provisioner.SCEPKeyManager) Option {
return func(a *Authority) error {
a.scepKeyManager = skm
return nil
}
}
// WithSSHUserSigner defines the signer used to sign SSH user certificates.
func WithSSHUserSigner(s crypto.Signer) Option {
return func(a *Authority) error {
@ -369,3 +400,16 @@ func readCertificateBundle(pemCerts []byte) ([]*x509.Certificate, error) {
}
return certs, nil
}
// WithMeter is an option that sets the authority's [Meter] to the provided one.
func WithMeter(m Meter) Option {
if m == nil {
m = noopMeter{}
}
return func(a *Authority) (_ error) {
a.meter = m
return
}
}

@ -154,7 +154,7 @@ func (a *Authority) checkProvisionerPolicy(ctx context.Context, provName string,
// checkPolicy checks if a new or updated policy configuration results in the user
// locking themselves or other admins out of the CA.
func (a *Authority) checkPolicy(ctx context.Context, currentAdmin *linkedca.Admin, otherAdmins []*linkedca.Admin, p *linkedca.Policy) error {
func (a *Authority) checkPolicy(_ context.Context, currentAdmin *linkedca.Admin, otherAdmins []*linkedca.Admin, p *linkedca.Policy) error {
// convert the policy; return early if nil
policyOptions := authPolicy.LinkedToCertificates(p)
if policyOptions == nil {
@ -248,7 +248,7 @@ func isAllowed(engine authPolicy.X509Policy, sans []string) error {
if isNamePolicyError && policyErr.Reason == policy.NotAllowed {
return &PolicyError{
Typ: AdminLockOut,
Err: fmt.Errorf("the provided policy would lock out %s from the CA. Please update your policy to include %s as an allowed name", sans, sans),
Err: fmt.Errorf("the provided policy would lock out %s from the CA. Please create an x509 policy to include %s as an allowed DNS name", sans, sans),
}
}
return &PolicyError{

@ -21,6 +21,7 @@ type HostPolicy policy.SSHNamePolicyEngine
func NewX509PolicyEngine(policyOptions X509PolicyOptionsInterface) (X509Policy, error) {
// return early if no policy engine options to configure
if policyOptions == nil {
//nolint:nilnil,nolintlint // expected values
return nil, nil
}
@ -50,6 +51,7 @@ func NewX509PolicyEngine(policyOptions X509PolicyOptionsInterface) (X509Policy,
// ensure no policy engine is returned when no name options were provided
if len(options) == 0 {
//nolint:nilnil,nolintlint // expected values
return nil, nil
}
@ -93,6 +95,7 @@ func NewSSHHostPolicyEngine(policyOptions SSHPolicyOptionsInterface) (HostPolicy
func newSSHPolicyEngine(policyOptions SSHPolicyOptionsInterface, typ sshPolicyEngineType) (policy.SSHNamePolicyEngine, error) {
// return early if no policy engine options to configure
if policyOptions == nil {
//nolint:nilnil,nolintlint // expected values
return nil, nil
}
@ -134,6 +137,7 @@ func newSSHPolicyEngine(policyOptions SSHPolicyOptionsInterface, typ sshPolicyEn
// ensure no policy engine is returned when no name options were provided
if len(options) == 0 {
//nolint:nilnil,nolintlint // expected values
return nil, nil
}

@ -6,8 +6,8 @@ import (
"reflect"
"testing"
"github.com/go-jose/go-jose/v3"
"github.com/stretchr/testify/assert"
"gopkg.in/square/go-jose.v2"
"go.step.sm/linkedca"
@ -80,7 +80,7 @@ func TestAuthority_checkPolicy(t *testing.T) {
},
err: &PolicyError{
Typ: AdminLockOut,
Err: errors.New("the provided policy would lock out [step] from the CA. Please update your policy to include [step] as an allowed name"),
Err: errors.New("the provided policy would lock out [step] from the CA. Please create an x509 policy to include [step] as an allowed DNS name"),
},
}
},
@ -127,7 +127,7 @@ func TestAuthority_checkPolicy(t *testing.T) {
},
err: &PolicyError{
Typ: AdminLockOut,
Err: errors.New("the provided policy would lock out [otherAdmin] from the CA. Please update your policy to include [otherAdmin] as an allowed name"),
Err: errors.New("the provided policy would lock out [otherAdmin] from the CA. Please create an x509 policy to include [otherAdmin] as an allowed DNS name"),
},
}
},

@ -48,7 +48,7 @@ func (c ACMEChallenge) Validate() error {
type ACMEAttestationFormat string
const (
// APPLE is the format used to enable device-attest-01 on apple devices.
// APPLE is the format used to enable device-attest-01 on Apple devices.
APPLE ACMEAttestationFormat = "apple"
// STEP is the format used to enable device-attest-01 on devices that
@ -57,7 +57,7 @@ const (
// TODO(mariano): should we rename this to something else.
STEP ACMEAttestationFormat = "step"
// TPM is the format used to enable device-attest-01 on TPMs.
// TPM is the format used to enable device-attest-01 with TPMs.
TPM ACMEAttestationFormat = "tpm"
)
@ -84,6 +84,17 @@ type ACME struct {
Type string `json:"type"`
Name string `json:"name"`
ForceCN bool `json:"forceCN,omitempty"`
// TermsOfService contains a URL pointing to the ACME server's
// terms of service. Defaults to empty.
TermsOfService string `json:"termsOfService,omitempty"`
// Website contains an URL pointing to more information about
// the ACME server. Defaults to empty.
Website string `json:"website,omitempty"`
// CaaIdentities is an array of hostnames that the ACME server
// identifies itself with. These hostnames can be used by ACME
// clients to determine the correct issuer domain name to use
// when configuring CAA records. Defaults to empty array.
CaaIdentities []string `json:"caaIdentities,omitempty"`
// RequireEAB makes the provisioner require ACME EAB to be provided
// by clients when creating a new Account. If set to true, the provided
// EAB will be verified. If set to false and an EAB is provided, it is
@ -122,7 +133,7 @@ func (p *ACME) GetIDForToken() string {
}
// GetTokenID returns the identifier of the token.
func (p *ACME) GetTokenID(ott string) (string, error) {
func (p *ACME) GetTokenID(string) (string, error) {
return "", errors.New("acme provisioner does not implement GetTokenID")
}
@ -173,7 +184,7 @@ func (p *ACME) Init(config Config) (err error) {
}
// Parse attestation roots.
// The pool will be nil if the there are not roots.
// The pool will be nil if there are no roots.
if rest := p.AttestationRoots; len(rest) > 0 {
var block *pem.Block
var hasCert bool
@ -217,7 +228,7 @@ type ACMEIdentifier struct {
// AuthorizeOrderIdentifier verifies the provisioner is allowed to issue a
// certificate for an ACME Order Identifier.
func (p *ACME) AuthorizeOrderIdentifier(ctx context.Context, identifier ACMEIdentifier) error {
func (p *ACME) AuthorizeOrderIdentifier(_ context.Context, identifier ACMEIdentifier) error {
x509Policy := p.ctl.getPolicy().getX509()
// identifier is allowed if no policy is configured
@ -242,11 +253,11 @@ func (p *ACME) AuthorizeOrderIdentifier(ctx context.Context, identifier ACMEIden
// AuthorizeSign does not do any validation, because all validation is handled
// in the ACME protocol. This method returns a list of modifiers / constraints
// on the resulting certificate.
func (p *ACME) AuthorizeSign(ctx context.Context, token string) ([]SignOption, error) {
func (p *ACME) AuthorizeSign(context.Context, string) ([]SignOption, error) {
opts := []SignOption{
p,
// modifiers / withOptions
newProvisionerExtensionOption(TypeACME, p.Name, ""),
newProvisionerExtensionOption(TypeACME, p.Name, "").WithControllerOptions(p.ctl),
newForceCNOption(p.ForceCN),
profileDefaultDuration(p.ctl.Claimer.DefaultTLSCertDuration()),
// validators
@ -263,7 +274,7 @@ func (p *ACME) AuthorizeSign(ctx context.Context, token string) ([]SignOption, e
// the CA. It can be used to authorize revocation of a certificate. With the
// ACME protocol, revocation authorization is specified and performed as part
// of the client/server interaction, so this is a no-op.
func (p *ACME) AuthorizeRevoke(ctx context.Context, token string) error {
func (p *ACME) AuthorizeRevoke(context.Context, string) error {
return nil
}
@ -278,7 +289,7 @@ func (p *ACME) AuthorizeRenew(ctx context.Context, cert *x509.Certificate) error
// IsChallengeEnabled checks if the given challenge is enabled. By default
// http-01, dns-01 and tls-alpn-01 are enabled, to disable any of them the
// Challenge provisioner property should have at least one element.
func (p *ACME) IsChallengeEnabled(ctx context.Context, challenge ACMEChallenge) bool {
func (p *ACME) IsChallengeEnabled(_ context.Context, challenge ACMEChallenge) bool {
enabledChallenges := []ACMEChallenge{
HTTP_01, DNS_01, TLS_ALPN_01,
}
@ -296,7 +307,7 @@ func (p *ACME) IsChallengeEnabled(ctx context.Context, challenge ACMEChallenge)
// IsAttestationFormatEnabled checks if the given attestation format is enabled.
// By default apple, step and tpm are enabled, to disable any of them the
// AttestationFormat provisioner property should have at least one element.
func (p *ACME) IsAttestationFormatEnabled(ctx context.Context, format ACMEAttestationFormat) bool {
func (p *ACME) IsAttestationFormatEnabled(_ context.Context, format ACMEAttestationFormat) bool {
enabledFormats := []ACMEAttestationFormat{
APPLE, STEP, TPM,
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save