forked from TrueCloudLab/certificates
Merge branch 'master' into hs/acme-eab
This commit is contained in:
commit
66464ae302
30 changed files with 370 additions and 63 deletions
89
.github/workflows/release.yml
vendored
89
.github/workflows/release.yml
vendored
|
@ -12,7 +12,7 @@ jobs:
|
|||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
matrix:
|
||||
go: [ '1.15', '1.16' ]
|
||||
go: [ '1.15', '1.16', '1.17' ]
|
||||
outputs:
|
||||
is_prerelease: ${{ steps.is_prerelease.outputs.IS_PRERELEASE }}
|
||||
steps:
|
||||
|
@ -62,8 +62,15 @@ jobs:
|
|||
needs: test
|
||||
runs-on: ubuntu-20.04
|
||||
outputs:
|
||||
debversion: ${{ steps.extract-tag.outputs.DEB_VERSION }}
|
||||
is_prerelease: ${{ steps.is_prerelease.outputs.IS_PRERELEASE }}
|
||||
steps:
|
||||
-
|
||||
name: Extract Tag Names
|
||||
id: extract-tag
|
||||
run: |
|
||||
DEB_VERSION=$(echo ${GITHUB_REF#refs/tags/v} | sed 's/-/./')
|
||||
echo "::set-output name=DEB_VERSION::${DEB_VERSION}"
|
||||
-
|
||||
name: Is Pre-release
|
||||
id: is_prerelease
|
||||
|
@ -99,62 +106,71 @@ jobs:
|
|||
name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.16
|
||||
-
|
||||
name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@56f5b77f7fa4a8fe068bf22b732ec036cc9bc13f # v2.4.1
|
||||
with:
|
||||
version: latest
|
||||
args: release --rm-dist
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.PAT }}
|
||||
|
||||
release_deb:
|
||||
name: Build & Upload Debian Package To Github
|
||||
runs-on: ubuntu-20.04
|
||||
needs: create_release
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
-
|
||||
name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: '1.16'
|
||||
go-version: 1.17
|
||||
-
|
||||
name: APT Install
|
||||
id: aptInstall
|
||||
run: sudo apt-get -y install build-essential debhelper fakeroot
|
||||
-
|
||||
name: Build Debian package
|
||||
id: build
|
||||
id: make_debian
|
||||
run: |
|
||||
PATH=$PATH:/usr/local/go/bin:/home/admin/go/bin
|
||||
make debian
|
||||
# need to restore the git state otherwise goreleaser fails due to dirty state
|
||||
git restore debian/changelog
|
||||
git clean -fd
|
||||
-
|
||||
name: Upload Debian Package
|
||||
id: upload_deb
|
||||
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: Get Release Date
|
||||
id: release_date
|
||||
run: |
|
||||
tag_name="${GITHUB_REF##*/}"
|
||||
hub release edit $(find ./.releases -type f -printf "-a %p ") -m "" "$tag_name"
|
||||
RELEASE_DATE=$(date +"%y-%m-%d")
|
||||
echo "::set-output name=RELEASE_DATE::${RELEASE_DATE}"
|
||||
-
|
||||
name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@5a54d7e660bda43b405e8463261b3d25631ffe86 # v2.7.0
|
||||
with:
|
||||
version: latest
|
||||
args: release --rm-dist
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.PAT }}
|
||||
COSIGN_PWD: ${{ secrets.COSIGN_PWD }}
|
||||
DEB_VERSION: ${{ needs.create_release.outputs.debversion }}
|
||||
RELEASE_DATE: ${{ steps.release_date.outputs.RELEASE_DATE }}
|
||||
|
||||
build_upload_docker:
|
||||
name: Build & Upload Docker Images
|
||||
runs-on: ubuntu-20.04
|
||||
needs: test
|
||||
steps:
|
||||
- name: Checkout
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Setup Go
|
||||
-
|
||||
name: Setup Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: '1.16'
|
||||
- name: Build
|
||||
go-version: '1.17'
|
||||
-
|
||||
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
|
||||
|
@ -162,3 +178,4 @@ jobs:
|
|||
env:
|
||||
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
|
||||
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
|
||||
COSIGN_PWD: ${{ secrets.COSIGN_PWD }}
|
||||
|
|
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
|
@ -14,7 +14,7 @@ jobs:
|
|||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
matrix:
|
||||
go: [ '1.15', '1.16' ]
|
||||
go: [ '1.15', '1.16', '1.17' ]
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
|
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -14,8 +14,8 @@
|
|||
|
||||
# Others
|
||||
*.swp
|
||||
.travis-releases
|
||||
.releases
|
||||
coverage.txt
|
||||
vendor
|
||||
output
|
||||
vendor
|
||||
.idea
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
# This is an example .goreleaser.yml file with some sane defaults.
|
||||
# Make sure to check the documentation at http://goreleaser.com
|
||||
project_name: step-ca
|
||||
|
||||
before:
|
||||
hooks:
|
||||
# You may remove this if you don't use go modules.
|
||||
- go mod download
|
||||
|
||||
builds:
|
||||
-
|
||||
id: step-ca
|
||||
|
@ -93,6 +95,7 @@ builds:
|
|||
binary: bin/step-awskms-init
|
||||
ldflags:
|
||||
- -w -X main.Version={{.Version}} -X main.BuildTime={{.Date}}
|
||||
|
||||
archives:
|
||||
-
|
||||
# Can be used to change the archive formats for specific GOOSs.
|
||||
|
@ -106,13 +109,25 @@ archives:
|
|||
files:
|
||||
- README.md
|
||||
- LICENSE
|
||||
|
||||
source:
|
||||
enabled: true
|
||||
name_template: '{{ .ProjectName }}_{{ .Version }}'
|
||||
|
||||
checksum:
|
||||
name_template: 'checksums.txt'
|
||||
extra_files:
|
||||
- glob: ./.releases/*
|
||||
|
||||
signs:
|
||||
- cmd: cosign
|
||||
stdin: '{{ .Env.COSIGN_PWD }}'
|
||||
args: ["sign-blob", "-key=/tmp/cosign.key", "-output=${signature}", "${artifact}"]
|
||||
artifacts: all
|
||||
|
||||
snapshot:
|
||||
name_template: "{{ .Tag }}-next"
|
||||
|
||||
release:
|
||||
# Repo in which the release will be created.
|
||||
# Default is extracted from the origin remote URL or empty if its private hosted.
|
||||
|
@ -139,7 +154,55 @@ release:
|
|||
|
||||
# You can change the name of the release.
|
||||
# Default is `{{.Tag}}`
|
||||
#name_template: "{{.ProjectName}}-v{{.Version}} {{.Env.USER}}"
|
||||
name_template: "Step CA {{ .Tag }} ({{ .Env.RELEASE_DATE }})"
|
||||
|
||||
# Header template for the release body.
|
||||
# Defaults to empty.
|
||||
header: |
|
||||
## Official Release Artifacts
|
||||
|
||||
#### Linux
|
||||
|
||||
- 📦 [step-ca_linux_{{ .Version }}_amd64.tar.gz](https://dl.step.sm/certificates/{{ .Tag }}/step-ca_linux_{{ .Version }}_amd64.tar.gz)
|
||||
- 📦 [step-ca_{{ .Env.DEB_VERSION }}_amd64.deb](https://dl.step.sm/certificates/{{ .Tag }}/step-ca_{{ .Env.DEB_VERSION }}_amd64.deb)
|
||||
|
||||
#### OSX Darwin
|
||||
|
||||
- 📦 [step-ca_darwin_{{ .Version }}_amd64.tar.gz](https://dl.step.sm/certificates/{{ .Tag }}/step-ca_darwin_{{ .Version }}_amd64.tar.gz)
|
||||
- 📦 [step-ca_darwin_{{ .Version }}_arm64.tar.gz](https://dl.step.sm/certificates/{{ .Tag }}/step-ca_darwin_{{ .Version }}_arm64.tar.gz)
|
||||
|
||||
#### Windows
|
||||
|
||||
- 📦 [step-ca_windows_{{ .Version }}_arm64.zip](https://dl.step.sm/certificates/{{ .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).
|
||||
|
||||
Don't see the artifact you need? Open an issue [here](https://github.com/smallstep/certificates/issues/new/choose).
|
||||
|
||||
## Signatures and Checksums
|
||||
|
||||
`step-ca` uses [sigstore/cosign](https://github.com/sigstore/cosign) for signing and verifying release artifacts.
|
||||
|
||||
Below is an example using `cosign` to verify a release artifact:
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
The `checksums.txt` file (in the `Assets` section below) contains a checksum for every artifact in the release.
|
||||
|
||||
# Footer template for the release body.
|
||||
# Defaults to empty.
|
||||
footer: |
|
||||
## Thanks!
|
||||
|
||||
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.
|
||||
|
||||
# You can disable this pipe in order to not upload any artifacts.
|
||||
# Defaults to false.
|
||||
|
@ -149,6 +212,8 @@ release:
|
|||
# The filename on the release will be the last part of the path (base). If
|
||||
# another file with the same name exists, the latest one found will be used.
|
||||
# Defaults to empty.
|
||||
extra_files:
|
||||
- glob: ./.releases/*
|
||||
#extra_files:
|
||||
# - glob: ./path/to/file.txt
|
||||
# - glob: ./glob/**/to/**/file/**/*
|
||||
|
|
29
CHANGELOG.md
29
CHANGELOG.md
|
@ -4,10 +4,37 @@ 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).
|
||||
|
||||
## [Unreleased - 0.0.1] - DATE
|
||||
## [Unreleased - 0.17.3] - DATE
|
||||
### Added
|
||||
- go 1.17 to github action test matrix
|
||||
- Support for CloudKMS RSA-PSS signers without using templates.
|
||||
### Changed
|
||||
- Using go 1.17 for binaries
|
||||
### Deprecated
|
||||
### Removed
|
||||
### Fixed
|
||||
### 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.
|
||||
|
||||
|
|
4
Makefile
4
Makefile
|
@ -29,7 +29,7 @@ ci: testcgo build
|
|||
|
||||
bootstra%:
|
||||
# Using a released version of golangci-lint to take into account custom replacements in their go.mod
|
||||
$Q curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(shell go env GOPATH)/bin v1.39.0
|
||||
$Q curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(shell go env GOPATH)/bin v1.42.0
|
||||
|
||||
.PHONY: bootstra%
|
||||
|
||||
|
@ -68,7 +68,7 @@ PUSHTYPE := branch
|
|||
endif
|
||||
|
||||
VERSION := $(shell echo $(VERSION) | sed 's/^v//')
|
||||
DEB_VERSION := $(shell echo $(VERSION) | sed 's/-/~/g')
|
||||
DEB_VERSION := $(shell echo $(VERSION) | sed 's/-/./g')
|
||||
|
||||
ifdef V
|
||||
$(info TRAVIS_TAG is $(TRAVIS_TAG))
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"net"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/smallstep/assert"
|
||||
|
@ -82,6 +83,10 @@ func testAuthority(t *testing.T, opts ...Option) *Authority {
|
|||
}
|
||||
a, err := New(c, opts...)
|
||||
assert.FatalError(t, err)
|
||||
// Avoid errors when test tokens are created before the test authority. This
|
||||
// happens in some tests where we re-create the same authority to test
|
||||
// special cases without re-creating the token.
|
||||
a.startTime = a.startTime.Add(-1 * time.Minute)
|
||||
return a
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ func (p provisionerSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
|||
// provisioner.
|
||||
type loadByTokenPayload struct {
|
||||
jose.Claims
|
||||
Email string `json:"email"` // OIDC email
|
||||
AuthorizedParty string `json:"azp"` // OIDC client id
|
||||
TenantID string `json:"tid"` // Microsoft Azure tenant id
|
||||
}
|
||||
|
@ -129,12 +130,20 @@ func (c *Collection) LoadByToken(token *jose.JSONWebToken, claims *jose.Claims)
|
|||
return p, ok
|
||||
}
|
||||
}
|
||||
// Try with tid (Azure)
|
||||
// Try with tid (Azure, Azure OIDC)
|
||||
if payload.TenantID != "" {
|
||||
// Try to load an OIDC provisioner first.
|
||||
if payload.Email != "" {
|
||||
if p, ok := c.LoadByTokenID(payload.Audience[0]); ok {
|
||||
return p, ok
|
||||
}
|
||||
}
|
||||
// Try to load an Azure provisioner.
|
||||
if p, ok := c.LoadByTokenID(payload.TenantID); ok {
|
||||
return p, ok
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to aud
|
||||
return c.LoadByTokenID(payload.Audience[0])
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"math/big"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
@ -455,10 +456,10 @@ func containsAllMembers(group, subgroup []string) bool {
|
|||
}
|
||||
visit := make(map[string]struct{}, lg)
|
||||
for i := 0; i < lg; i++ {
|
||||
visit[group[i]] = struct{}{}
|
||||
visit[strings.ToLower(group[i])] = struct{}{}
|
||||
}
|
||||
for i := 0; i < lsg; i++ {
|
||||
if _, ok := visit[subgroup[i]]; !ok {
|
||||
if _, ok := visit[strings.ToLower(subgroup[i])]; !ok {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package apiv1
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
@ -26,6 +27,12 @@ type CertificateAuthorityCreator interface {
|
|||
CreateCertificateAuthority(req *CreateCertificateAuthorityRequest) (*CreateCertificateAuthorityResponse, error)
|
||||
}
|
||||
|
||||
// SignatureAlgorithmGetter is an optional implementation in a crypto.Signer
|
||||
// that returns the SignatureAlgorithm to use.
|
||||
type SignatureAlgorithmGetter interface {
|
||||
SignatureAlgorithm() x509.SignatureAlgorithm
|
||||
}
|
||||
|
||||
// Type represents the CAS type used.
|
||||
type Type string
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ func (c *SoftCAS) CreateCertificate(req *apiv1.CreateCertificateRequest) (*apiv1
|
|||
}
|
||||
req.Template.Issuer = c.CertificateChain[0].Subject
|
||||
|
||||
cert, err := x509util.CreateCertificate(req.Template, c.CertificateChain[0], req.Template.PublicKey, c.Signer)
|
||||
cert, err := createCertificate(req.Template, c.CertificateChain[0], req.Template.PublicKey, c.Signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ func (c *SoftCAS) RenewCertificate(req *apiv1.RenewCertificateRequest) (*apiv1.R
|
|||
req.Template.NotAfter = t.Add(req.Lifetime)
|
||||
req.Template.Issuer = c.CertificateChain[0].Subject
|
||||
|
||||
cert, err := x509util.CreateCertificate(req.Template, c.CertificateChain[0], req.Template.PublicKey, c.Signer)
|
||||
cert, err := createCertificate(req.Template, c.CertificateChain[0], req.Template.PublicKey, c.Signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -150,12 +150,12 @@ func (c *SoftCAS) CreateCertificateAuthority(req *apiv1.CreateCertificateAuthori
|
|||
var cert *x509.Certificate
|
||||
switch req.Type {
|
||||
case apiv1.RootCA:
|
||||
cert, err = x509util.CreateCertificate(req.Template, req.Template, signer.Public(), signer)
|
||||
cert, err = createCertificate(req.Template, req.Template, signer.Public(), signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case apiv1.IntermediateCA:
|
||||
cert, err = x509util.CreateCertificate(req.Template, req.Parent.Certificate, signer.Public(), req.Parent.Signer)
|
||||
cert, err = createCertificate(req.Template, req.Parent.Certificate, signer.Public(), req.Parent.Signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -210,3 +210,16 @@ func (c *SoftCAS) createSigner(req *kmsapi.CreateSignerRequest) (crypto.Signer,
|
|||
}
|
||||
return c.KeyManager.CreateSigner(req)
|
||||
}
|
||||
|
||||
// createCertificate sets the SignatureAlgorithm of the template if necessary
|
||||
// and calls x509util.CreateCertificate.
|
||||
func createCertificate(template, parent *x509.Certificate, pub crypto.PublicKey, signer crypto.Signer) (*x509.Certificate, error) {
|
||||
// Signers can specify the signature algorithm. This is especially important
|
||||
// when x509.CreateCertificate attempts to validate a RSAPSS signature.
|
||||
if template.SignatureAlgorithm == 0 {
|
||||
if sa, ok := signer.(apiv1.SignatureAlgorithmGetter); ok {
|
||||
template.SignatureAlgorithm = sa.SignatureAlgorithm()
|
||||
}
|
||||
}
|
||||
return x509util.CreateCertificate(template, parent, pub, signer)
|
||||
}
|
||||
|
|
|
@ -75,6 +75,15 @@ var (
|
|||
testSignedIntermediateTemplate = mustSign(testIntermediateTemplate, testSignedRootTemplate, testNow, testNow.Add(24*time.Hour))
|
||||
)
|
||||
|
||||
type signatureAlgorithmSigner struct {
|
||||
crypto.Signer
|
||||
algorithm x509.SignatureAlgorithm
|
||||
}
|
||||
|
||||
func (s *signatureAlgorithmSigner) SignatureAlgorithm() x509.SignatureAlgorithm {
|
||||
return s.algorithm
|
||||
}
|
||||
|
||||
type mockKeyManager struct {
|
||||
signer crypto.Signer
|
||||
errGetPublicKey error
|
||||
|
@ -247,6 +256,13 @@ func TestSoftCAS_CreateCertificate(t *testing.T) {
|
|||
tmplNoSerial := *testTemplate
|
||||
tmplNoSerial.SerialNumber = nil
|
||||
|
||||
saTemplate := *testSignedTemplate
|
||||
saTemplate.SignatureAlgorithm = 0
|
||||
saSigner := &signatureAlgorithmSigner{
|
||||
Signer: testSigner,
|
||||
algorithm: x509.PureEd25519,
|
||||
}
|
||||
|
||||
type fields struct {
|
||||
Issuer *x509.Certificate
|
||||
Signer crypto.Signer
|
||||
|
@ -267,6 +283,12 @@ func TestSoftCAS_CreateCertificate(t *testing.T) {
|
|||
Certificate: testSignedTemplate,
|
||||
CertificateChain: []*x509.Certificate{testIssuer},
|
||||
}, false},
|
||||
{"ok signature algorithm", fields{testIssuer, saSigner}, args{&apiv1.CreateCertificateRequest{
|
||||
Template: &saTemplate, Lifetime: 24 * time.Hour,
|
||||
}}, &apiv1.CreateCertificateResponse{
|
||||
Certificate: testSignedTemplate,
|
||||
CertificateChain: []*x509.Certificate{testIssuer},
|
||||
}, false},
|
||||
{"ok with notBefore", fields{testIssuer, testSigner}, args{&apiv1.CreateCertificateRequest{
|
||||
Template: &tmplNotBefore, Lifetime: 24 * time.Hour,
|
||||
}}, &apiv1.CreateCertificateResponse{
|
||||
|
@ -316,6 +338,11 @@ func TestSoftCAS_RenewCertificate(t *testing.T) {
|
|||
tmplNoSerial := *testTemplate
|
||||
tmplNoSerial.SerialNumber = nil
|
||||
|
||||
saSigner := &signatureAlgorithmSigner{
|
||||
Signer: testSigner,
|
||||
algorithm: x509.PureEd25519,
|
||||
}
|
||||
|
||||
type fields struct {
|
||||
Issuer *x509.Certificate
|
||||
Signer crypto.Signer
|
||||
|
@ -336,6 +363,12 @@ func TestSoftCAS_RenewCertificate(t *testing.T) {
|
|||
Certificate: testSignedTemplate,
|
||||
CertificateChain: []*x509.Certificate{testIssuer},
|
||||
}, false},
|
||||
{"ok signature algorithm", fields{testIssuer, saSigner}, args{&apiv1.RenewCertificateRequest{
|
||||
Template: testTemplate, Lifetime: 24 * time.Hour,
|
||||
}}, &apiv1.RenewCertificateResponse{
|
||||
Certificate: testSignedTemplate,
|
||||
CertificateChain: []*x509.Certificate{testIssuer},
|
||||
}, false},
|
||||
{"fail template", fields{testIssuer, testSigner}, args{&apiv1.RenewCertificateRequest{Lifetime: 24 * time.Hour}}, nil, true},
|
||||
{"fail lifetime", fields{testIssuer, testSigner}, args{&apiv1.RenewCertificateRequest{Template: testTemplate}}, nil, true},
|
||||
{"fail CreateCertificate", fields{testIssuer, testSigner}, args{&apiv1.RenewCertificateRequest{
|
||||
|
@ -425,6 +458,11 @@ func Test_now(t *testing.T) {
|
|||
func TestSoftCAS_CreateCertificateAuthority(t *testing.T) {
|
||||
mockNow(t)
|
||||
|
||||
saSigner := &signatureAlgorithmSigner{
|
||||
Signer: testSigner,
|
||||
algorithm: x509.PureEd25519,
|
||||
}
|
||||
|
||||
type fields struct {
|
||||
Issuer *x509.Certificate
|
||||
Signer crypto.Signer
|
||||
|
@ -467,6 +505,17 @@ func TestSoftCAS_CreateCertificateAuthority(t *testing.T) {
|
|||
PrivateKey: testSigner,
|
||||
Signer: testSigner,
|
||||
}, false},
|
||||
{"ok signature algorithm", fields{nil, nil, &mockKeyManager{signer: saSigner}}, args{&apiv1.CreateCertificateAuthorityRequest{
|
||||
Type: apiv1.RootCA,
|
||||
Template: testRootTemplate,
|
||||
Lifetime: 24 * time.Hour,
|
||||
}}, &apiv1.CreateCertificateAuthorityResponse{
|
||||
Name: "Test Root CA",
|
||||
Certificate: testSignedRootTemplate,
|
||||
PublicKey: testSignedRootTemplate.PublicKey,
|
||||
PrivateKey: saSigner,
|
||||
Signer: saSigner,
|
||||
}, false},
|
||||
{"fail template", fields{nil, nil, &mockKeyManager{}}, args{&apiv1.CreateCertificateAuthorityRequest{
|
||||
Type: apiv1.RootCA,
|
||||
Lifetime: 24 * time.Hour,
|
||||
|
|
4
cosign.pub
Normal file
4
cosign.pub
Normal file
|
@ -0,0 +1,4 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEs+6THbAiXx4bja5ARQFNZmPwZjlD
|
||||
GRvt5H+9ZFDhrcFPR1E7eB2rt1B/DhobANdHGKjvEBZEf0v4X/7S+SHrIw==
|
||||
-----END PUBLIC KEY-----
|
8
go.mod
8
go.mod
|
@ -17,7 +17,7 @@ require (
|
|||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
|
||||
github.com/mattn/go-colorable v0.1.8 // indirect
|
||||
github.com/mattn/go-isatty v0.0.13 // indirect
|
||||
github.com/micromdm/scep/v2 v2.0.0
|
||||
github.com/micromdm/scep/v2 v2.1.0
|
||||
github.com/newrelic/go-agent v2.15.0+incompatible
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/rs/xid v1.2.1
|
||||
|
@ -25,7 +25,7 @@ require (
|
|||
github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262
|
||||
github.com/smallstep/nosql v0.3.8
|
||||
github.com/urfave/cli v1.22.4
|
||||
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1
|
||||
go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352
|
||||
go.step.sm/cli-utils v0.4.1
|
||||
go.step.sm/crypto v0.9.2
|
||||
go.step.sm/linkedca v0.5.0
|
||||
|
@ -42,7 +42,3 @@ require (
|
|||
// replace go.step.sm/crypto => ../crypto
|
||||
// replace go.step.sm/cli-utils => ../cli-utils
|
||||
// replace go.step.sm/linkedca => ../linkedca
|
||||
|
||||
//replace go.step.sm/linkedca => ../linkedca
|
||||
|
||||
replace go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1 => github.com/omorsi/pkcs7 v0.0.0-20210217142924-a7b80a2a8568
|
||||
|
|
9
go.sum
9
go.sum
|
@ -358,8 +358,8 @@ github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1y
|
|||
github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/micromdm/scep/v2 v2.0.0 h1:cRzcY0S5QX+0+J+7YC4P2uZSnfMup8S8zJu/bLFgOkA=
|
||||
github.com/micromdm/scep/v2 v2.0.0/go.mod h1:ouaDs5tcjOjdHD/h8BGaQsWE87MUnQ/wMTMgfMMIpPc=
|
||||
github.com/micromdm/scep/v2 v2.1.0 h1:2fS9Rla7qRR266hvUoEauBJ7J6FhgssEiq2OkSKXmaU=
|
||||
github.com/micromdm/scep/v2 v2.1.0/go.mod h1:BkF7TkPPhmgJAMtHfP+sFTKXmgzNJgLQlvvGoOExBcc=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/pkcs11 v1.0.3-0.20190429190417-a667d056470f h1:eVB9ELsoq5ouItQBr5Tj334bhPJG/MX+m7rTchmzVUQ=
|
||||
github.com/miekg/pkcs11 v1.0.3-0.20190429190417-a667d056470f/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||
|
@ -392,8 +392,6 @@ github.com/newrelic/go-agent v2.15.0+incompatible/go.mod h1:a8Fv1b/fYhFSReoTU6HD
|
|||
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
github.com/omorsi/pkcs7 v0.0.0-20210217142924-a7b80a2a8568 h1:+MPqEswjYiS0S1FCTg8MIhMBMzxiVQ94rooFwvPPiWk=
|
||||
github.com/omorsi/pkcs7 v0.0.0-20210217142924-a7b80a2a8568/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
|
@ -510,6 +508,9 @@ go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
|||
go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0=
|
||||
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
|
||||
go.mozilla.org/pkcs7 v0.0.0-20210730143726-725912489c62/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk=
|
||||
go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 h1:CCriYyAfq1Br1aIYettdHZTy8mBTIPo7We18TuO/bak=
|
||||
go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
|
|
|
@ -3,6 +3,7 @@ package cloudkms
|
|||
import (
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/x509"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -63,6 +64,19 @@ var signatureAlgorithmMapping = map[apiv1.SignatureAlgorithm]interface{}{
|
|||
apiv1.ECDSAWithSHA384: kmspb.CryptoKeyVersion_EC_SIGN_P384_SHA384,
|
||||
}
|
||||
|
||||
var cryptoKeyVersionMapping = map[kmspb.CryptoKeyVersion_CryptoKeyVersionAlgorithm]x509.SignatureAlgorithm{
|
||||
kmspb.CryptoKeyVersion_EC_SIGN_P256_SHA256: x509.ECDSAWithSHA256,
|
||||
kmspb.CryptoKeyVersion_EC_SIGN_P384_SHA384: x509.ECDSAWithSHA384,
|
||||
kmspb.CryptoKeyVersion_RSA_SIGN_PKCS1_2048_SHA256: x509.SHA256WithRSA,
|
||||
kmspb.CryptoKeyVersion_RSA_SIGN_PKCS1_3072_SHA256: x509.SHA256WithRSA,
|
||||
kmspb.CryptoKeyVersion_RSA_SIGN_PKCS1_4096_SHA256: x509.SHA256WithRSA,
|
||||
kmspb.CryptoKeyVersion_RSA_SIGN_PKCS1_4096_SHA512: x509.SHA512WithRSA,
|
||||
kmspb.CryptoKeyVersion_RSA_SIGN_PSS_2048_SHA256: x509.SHA256WithRSAPSS,
|
||||
kmspb.CryptoKeyVersion_RSA_SIGN_PSS_3072_SHA256: x509.SHA256WithRSAPSS,
|
||||
kmspb.CryptoKeyVersion_RSA_SIGN_PSS_4096_SHA256: x509.SHA256WithRSAPSS,
|
||||
kmspb.CryptoKeyVersion_RSA_SIGN_PSS_4096_SHA512: x509.SHA512WithRSAPSS,
|
||||
}
|
||||
|
||||
// KeyManagementClient defines the methods on KeyManagementClient that this
|
||||
// package will use. This interface will be used for unit testing.
|
||||
type KeyManagementClient interface {
|
||||
|
|
|
@ -2,6 +2,7 @@ package cloudkms
|
|||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/x509"
|
||||
"io"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
@ -13,6 +14,7 @@ import (
|
|||
type Signer struct {
|
||||
client KeyManagementClient
|
||||
signingKey string
|
||||
algorithm x509.SignatureAlgorithm
|
||||
publicKey crypto.PublicKey
|
||||
}
|
||||
|
||||
|
@ -40,7 +42,7 @@ func (s *Signer) preloadKey(signingKey string) error {
|
|||
if err != nil {
|
||||
return errors.Wrap(err, "cloudKMS GetPublicKey failed")
|
||||
}
|
||||
|
||||
s.algorithm = cryptoKeyVersionMapping[response.Algorithm]
|
||||
s.publicKey, err = pemutil.ParseKey([]byte(response.Pem))
|
||||
return err
|
||||
}
|
||||
|
@ -84,3 +86,10 @@ func (s *Signer) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]
|
|||
|
||||
return response.Signature, nil
|
||||
}
|
||||
|
||||
// SignatureAlgorithm returns the algorithm that must be specified in a
|
||||
// certificate to sign. This is specially important to distinguish RSA and
|
||||
// RSAPSS schemas.
|
||||
func (s *Signer) SignatureAlgorithm() x509.SignatureAlgorithm {
|
||||
return s.algorithm
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"crypto"
|
||||
"crypto/rand"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
@ -156,3 +157,79 @@ func Test_signer_Sign(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSigner_SignatureAlgorithm(t *testing.T) {
|
||||
pemBytes, err := ioutil.ReadFile("testdata/pub.pem")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
client := &MockClient{
|
||||
getPublicKey: func(_ context.Context, req *kmspb.GetPublicKeyRequest, _ ...gax.CallOption) (*kmspb.PublicKey, error) {
|
||||
var algorithm kmspb.CryptoKeyVersion_CryptoKeyVersionAlgorithm
|
||||
switch req.Name {
|
||||
case "ECDSA-SHA256":
|
||||
algorithm = kmspb.CryptoKeyVersion_EC_SIGN_P256_SHA256
|
||||
case "ECDSA-SHA384":
|
||||
algorithm = kmspb.CryptoKeyVersion_EC_SIGN_P384_SHA384
|
||||
case "SHA256-RSA-2048":
|
||||
algorithm = kmspb.CryptoKeyVersion_RSA_SIGN_PKCS1_2048_SHA256
|
||||
case "SHA256-RSA-3072":
|
||||
algorithm = kmspb.CryptoKeyVersion_RSA_SIGN_PKCS1_3072_SHA256
|
||||
case "SHA256-RSA-4096":
|
||||
algorithm = kmspb.CryptoKeyVersion_RSA_SIGN_PKCS1_4096_SHA256
|
||||
case "SHA512-RSA-4096":
|
||||
algorithm = kmspb.CryptoKeyVersion_RSA_SIGN_PKCS1_4096_SHA512
|
||||
case "SHA256-RSAPSS-2048":
|
||||
algorithm = kmspb.CryptoKeyVersion_RSA_SIGN_PSS_2048_SHA256
|
||||
case "SHA256-RSAPSS-3072":
|
||||
algorithm = kmspb.CryptoKeyVersion_RSA_SIGN_PSS_3072_SHA256
|
||||
case "SHA256-RSAPSS-4096":
|
||||
algorithm = kmspb.CryptoKeyVersion_RSA_SIGN_PSS_4096_SHA256
|
||||
case "SHA512-RSAPSS-4096":
|
||||
algorithm = kmspb.CryptoKeyVersion_RSA_SIGN_PSS_4096_SHA512
|
||||
}
|
||||
return &kmspb.PublicKey{
|
||||
Pem: string(pemBytes),
|
||||
Algorithm: algorithm,
|
||||
}, nil
|
||||
},
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
type fields struct {
|
||||
client KeyManagementClient
|
||||
signingKey string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
want x509.SignatureAlgorithm
|
||||
}{
|
||||
{"ECDSA-SHA256", fields{client, "ECDSA-SHA256"}, x509.ECDSAWithSHA256},
|
||||
{"ECDSA-SHA384", fields{client, "ECDSA-SHA384"}, x509.ECDSAWithSHA384},
|
||||
{"SHA256-RSA-2048", fields{client, "SHA256-RSA-2048"}, x509.SHA256WithRSA},
|
||||
{"SHA256-RSA-3072", fields{client, "SHA256-RSA-3072"}, x509.SHA256WithRSA},
|
||||
{"SHA256-RSA-4096", fields{client, "SHA256-RSA-4096"}, x509.SHA256WithRSA},
|
||||
{"SHA512-RSA-4096", fields{client, "SHA512-RSA-4096"}, x509.SHA512WithRSA},
|
||||
{"SHA256-RSAPSS-2048", fields{client, "SHA256-RSAPSS-2048"}, x509.SHA256WithRSAPSS},
|
||||
{"SHA256-RSAPSS-3072", fields{client, "SHA256-RSAPSS-3072"}, x509.SHA256WithRSAPSS},
|
||||
{"SHA256-RSAPSS-4096", fields{client, "SHA256-RSAPSS-4096"}, x509.SHA256WithRSAPSS},
|
||||
{"SHA512-RSAPSS-4096", fields{client, "SHA512-RSAPSS-4096"}, x509.SHA512WithRSAPSS},
|
||||
{"unknown", fields{client, "UNKNOWN"}, x509.UnknownSignatureAlgorithm},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
signer, err := NewSigner(tt.fields.client, tt.fields.signingKey)
|
||||
if err != nil {
|
||||
t.Errorf("NewSigner() error = %v", err)
|
||||
}
|
||||
if got := signer.SignatureAlgorithm(); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("Signer.SignatureAlgorithm() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
//go:build cgo
|
||||
// +build cgo
|
||||
|
||||
package pkcs11
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
//go:build opensc
|
||||
// +build opensc
|
||||
|
||||
package pkcs11
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
//go:build cgo && !softhsm2 && !yubihsm2 && !opensc
|
||||
// +build cgo,!softhsm2,!yubihsm2,!opensc
|
||||
|
||||
package pkcs11
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
//go:build cgo
|
||||
// +build cgo
|
||||
|
||||
package pkcs11
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
//go:build !cgo
|
||||
// +build !cgo
|
||||
|
||||
package pkcs11
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
//go:build cgo
|
||||
// +build cgo
|
||||
|
||||
package pkcs11
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
//go:build cgo
|
||||
// +build cgo
|
||||
|
||||
package pkcs11
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
//go:build cgo && softhsm2
|
||||
// +build cgo,softhsm2
|
||||
|
||||
package pkcs11
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
//go:build cgo && yubihsm2
|
||||
// +build cgo,yubihsm2
|
||||
|
||||
package pkcs11
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
//go:build cgo
|
||||
// +build cgo
|
||||
|
||||
package yubikey
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
//go:build !cgo
|
||||
// +build !cgo
|
||||
|
||||
package yubikey
|
||||
|
|
|
@ -54,6 +54,8 @@ define DOCKER_BUILDX
|
|||
# $(1) -- Image Tag
|
||||
# $(2) -- Push (empty is no push | --push will push to dockerhub)
|
||||
docker buildx build . --progress plain -t $(DOCKER_IMAGE_NAME):$(1) -f docker/Dockerfile.step-ca --platform="$(DOCKER_PLATFORMS)" $(2)
|
||||
echo -n "$(COSIGN_PWD)" | cosign sign -key /tmp/cosign.key -r $(DOCKER_IMAGE_NAME):$(1)
|
||||
|
||||
endef
|
||||
|
||||
# For non-master builds don't build the docker containers.
|
||||
|
|
Loading…
Reference in a new issue