forked from TrueCloudLab/certificates
Merge branch 'master' into cert-templates
This commit is contained in:
commit
aaaa7e9b4e
16 changed files with 473 additions and 145 deletions
83
Makefile
83
Makefile
|
@ -46,17 +46,25 @@ 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 VERSION is $(VERSION))
|
||||
$(info DEB_VERSION is $(DEB_VERSION))
|
||||
$(info PUSHTYPE is $(PUSHTYPE))
|
||||
endif
|
||||
|
||||
include make/docker.mk
|
||||
|
||||
#########################################
|
||||
# Build
|
||||
#########################################
|
||||
|
@ -167,82 +175,12 @@ run:
|
|||
|
||||
.PHONY: run
|
||||
|
||||
#########################################
|
||||
# Building Docker Image
|
||||
#
|
||||
# Builds a dockerfile for step by building a linux version of the step-cli and
|
||||
# then copying the specific binary when building the container.
|
||||
#
|
||||
# This ensures the container is as small as possible without having to deal
|
||||
# with getting access to private repositories inside the container during build
|
||||
# time.
|
||||
#########################################
|
||||
|
||||
# XXX We put the output for the build in 'output' so we don't mess with how we
|
||||
# do rule overriding from the base Makefile (if you name it 'build' it messes up
|
||||
# the wildcarding).
|
||||
DOCKER_OUTPUT=$(OUTPUT_ROOT)docker/
|
||||
|
||||
DOCKER_MAKE=V=$V GOOS_OVERRIDE='GOOS=linux GOARCH=amd64' PREFIX=$(1) make $(1)bin/$(2)
|
||||
DOCKER_BUILD=$Q docker build -t smallstep/$(1):latest -f docker/$(2) --build-arg BINPATH=$(DOCKER_OUTPUT)bin/$(1) .
|
||||
|
||||
docker: docker-make docker/Dockerfile.step-ca
|
||||
$(call DOCKER_BUILD,step-ca,Dockerfile.step-ca)
|
||||
|
||||
docker-make:
|
||||
mkdir -p $(DOCKER_OUTPUT)
|
||||
$(call DOCKER_MAKE,$(DOCKER_OUTPUT),step-ca)
|
||||
|
||||
.PHONY: docker docker-make
|
||||
|
||||
#################################################
|
||||
# Releasing Docker Images
|
||||
#
|
||||
# Using the docker build infrastructure, this section is responsible for
|
||||
# logging into docker hub and pushing the built docker containers up with the
|
||||
# appropriate tags.
|
||||
#################################################
|
||||
|
||||
DOCKER_TAG=docker tag smallstep/$(1):latest smallstep/$(1):$(2)
|
||||
DOCKER_PUSH=docker push smallstep/$(1):$(2)
|
||||
|
||||
docker-tag:
|
||||
$(call DOCKER_TAG,step-ca,$(VERSION))
|
||||
|
||||
docker-push-tag: docker-tag
|
||||
$(call DOCKER_PUSH,step-ca,$(VERSION))
|
||||
|
||||
docker-push-tag-latest:
|
||||
$(call DOCKER_PUSH,step-ca,latest)
|
||||
|
||||
# Rely on DOCKER_USERNAME and DOCKER_PASSWORD being set inside the CI or
|
||||
# equivalent environment
|
||||
docker-login:
|
||||
$Q docker login -u="$(DOCKER_USERNAME)" -p="$(DOCKER_PASSWORD)"
|
||||
|
||||
.PHONY: docker-login docker-tag docker-push-tag docker-push-tag-latest
|
||||
|
||||
#################################################
|
||||
# Targets for pushing the docker images
|
||||
#################################################
|
||||
|
||||
# For all builds we build the docker container
|
||||
docker-master: docker
|
||||
|
||||
# For all builds with a release candidate tag
|
||||
docker-release-candidate: docker-master docker-login docker-push-tag
|
||||
|
||||
# For all builds with a release tag
|
||||
docker-release: docker-release-candidate docker-push-tag-latest
|
||||
|
||||
.PHONY: docker-master docker-release-candidate docker-release
|
||||
|
||||
#########################################
|
||||
# Debian
|
||||
#########################################
|
||||
|
||||
changelog:
|
||||
$Q echo "step-certificates ($(VERSION)) unstable; urgency=medium" > debian/changelog
|
||||
$Q echo "step-certificates ($(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
|
||||
|
@ -323,6 +261,9 @@ artifacts-tag: artifacts-linux-tag artifacts-darwin-tag artifacts-archive-tag
|
|||
# Targets for creating step artifacts
|
||||
#################################################
|
||||
|
||||
# For all builds that are not tagged and not on the master branch
|
||||
artifacts-branch:
|
||||
|
||||
# For all builds that are not tagged
|
||||
artifacts-master:
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@ package api
|
|||
|
||||
import (
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
|
@ -162,6 +164,18 @@ func (h *Handler) GetCertificate(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
block, _ := pem.Decode(certBytes)
|
||||
if block == nil {
|
||||
api.WriteError(w, acme.ServerInternalErr(errors.New("failed to decode any certificates from generated certBytes")))
|
||||
return
|
||||
}
|
||||
cert, err := x509.ParseCertificate(block.Bytes)
|
||||
if err != nil {
|
||||
api.WriteError(w, acme.Wrap(err, "failed to parse generated leaf certificate"))
|
||||
return
|
||||
}
|
||||
|
||||
api.LogCertificate(w, cert)
|
||||
w.Header().Set("Content-Type", "application/pem-certificate-chain; charset=utf-8")
|
||||
w.Write(certBytes)
|
||||
}
|
||||
|
|
|
@ -526,6 +526,43 @@ func TestHandlerGetCertificate(t *testing.T) {
|
|||
problem: acme.ServerInternalErr(errors.New("force")),
|
||||
}
|
||||
},
|
||||
"fail/decode-leaf-for-loggger": func(t *testing.T) test {
|
||||
acc := &acme.Account{ID: "accID"}
|
||||
ctx := context.WithValue(context.Background(), acme.AccContextKey, acc)
|
||||
ctx = context.WithValue(ctx, chi.RouteCtxKey, chiCtx)
|
||||
return test{
|
||||
auth: &mockAcmeAuthority{
|
||||
getCertificate: func(accID, id string) ([]byte, error) {
|
||||
assert.Equals(t, accID, acc.ID)
|
||||
assert.Equals(t, id, certID)
|
||||
return []byte("foo"), nil
|
||||
},
|
||||
},
|
||||
ctx: ctx,
|
||||
statusCode: 500,
|
||||
problem: acme.ServerInternalErr(errors.New("failed to decode any certificates from generated certBytes")),
|
||||
}
|
||||
},
|
||||
"fail/parse-x509-leaf-for-logger": func(t *testing.T) test {
|
||||
acc := &acme.Account{ID: "accID"}
|
||||
ctx := context.WithValue(context.Background(), acme.AccContextKey, acc)
|
||||
ctx = context.WithValue(ctx, chi.RouteCtxKey, chiCtx)
|
||||
return test{
|
||||
auth: &mockAcmeAuthority{
|
||||
getCertificate: func(accID, id string) ([]byte, error) {
|
||||
assert.Equals(t, accID, acc.ID)
|
||||
assert.Equals(t, id, certID)
|
||||
return pem.EncodeToMemory(&pem.Block{
|
||||
Type: "CERTIFICATE REQUEST",
|
||||
Bytes: []byte("foo"),
|
||||
}), nil
|
||||
},
|
||||
},
|
||||
ctx: ctx,
|
||||
statusCode: 500,
|
||||
problem: acme.ServerInternalErr(errors.New("failed to parse generated leaf certificate")),
|
||||
}
|
||||
},
|
||||
"ok": func(t *testing.T) test {
|
||||
acc := &acme.Account{ID: "accID"}
|
||||
ctx := context.WithValue(context.Background(), acme.AccContextKey, acc)
|
||||
|
@ -565,7 +602,7 @@ func TestHandlerGetCertificate(t *testing.T) {
|
|||
prob := tc.problem.ToACME()
|
||||
|
||||
assert.Equals(t, ae.Type, prob.Type)
|
||||
assert.Equals(t, ae.Detail, prob.Detail)
|
||||
assert.HasPrefix(t, ae.Detail, prob.Detail)
|
||||
assert.Equals(t, ae.Identifier, prob.Identifier)
|
||||
assert.Equals(t, ae.Subproblems, prob.Subproblems)
|
||||
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
|
||||
|
|
|
@ -395,7 +395,8 @@ func logOtt(w http.ResponseWriter, token string) {
|
|||
}
|
||||
}
|
||||
|
||||
func logCertificate(w http.ResponseWriter, cert *x509.Certificate) {
|
||||
// LogCertificate add 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{}{
|
||||
"serial": cert.SerialNumber,
|
||||
|
@ -413,7 +414,11 @@ func logCertificate(w http.ResponseWriter, cert *x509.Certificate) {
|
|||
if err != nil || len(rest) > 0 {
|
||||
break
|
||||
}
|
||||
m["provisioner"] = fmt.Sprintf("%s (%s)", val.Name, val.CredentialID)
|
||||
if len(val.CredentialID) > 0 {
|
||||
m["provisioner"] = fmt.Sprintf("%s (%s)", val.Name, val.CredentialID)
|
||||
} else {
|
||||
m["provisioner"] = fmt.Sprintf("%s", val.Name)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ func (h *caHandler) Rekey(w http.ResponseWriter, r *http.Request) {
|
|||
caPEM = certChainPEM[1]
|
||||
}
|
||||
|
||||
logCertificate(w, certChain[0])
|
||||
LogCertificate(w, certChain[0])
|
||||
JSONStatus(w, &SignResponse{
|
||||
ServerPEM: certChainPEM[0],
|
||||
CaPEM: caPEM,
|
||||
|
|
|
@ -25,7 +25,7 @@ func (h *caHandler) Renew(w http.ResponseWriter, r *http.Request) {
|
|||
caPEM = certChainPEM[1]
|
||||
}
|
||||
|
||||
logCertificate(w, certChain[0])
|
||||
LogCertificate(w, certChain[0])
|
||||
JSONStatus(w, &SignResponse{
|
||||
ServerPEM: certChainPEM[0],
|
||||
CaPEM: caPEM,
|
||||
|
|
|
@ -91,7 +91,7 @@ func (h *caHandler) Revoke(w http.ResponseWriter, r *http.Request) {
|
|||
// TODO: should probably be checking if the certificate was revoked here.
|
||||
// Will need to thread that request down to the authority, so will need
|
||||
// to add API for that.
|
||||
logCertificate(w, opts.Crt)
|
||||
LogCertificate(w, opts.Crt)
|
||||
opts.MTLS = true
|
||||
}
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ func (h *caHandler) Sign(w http.ResponseWriter, r *http.Request) {
|
|||
if len(certChainPEM) > 1 {
|
||||
caPEM = certChainPEM[1]
|
||||
}
|
||||
logCertificate(w, certChain[0])
|
||||
LogCertificate(w, certChain[0])
|
||||
JSONStatus(w, &SignResponse{
|
||||
ServerPEM: certChainPEM[0],
|
||||
CaPEM: caPEM,
|
||||
|
|
|
@ -30,6 +30,19 @@ const awsIdentityURL = "http://169.254.169.254/latest/dynamic/instance-identity/
|
|||
// awsSignatureURL is the url used to retrieve the instance identity signature.
|
||||
const awsSignatureURL = "http://169.254.169.254/latest/dynamic/instance-identity/signature"
|
||||
|
||||
// awsAPITokenURL is the url used to get the IMDSv2 API token
|
||||
const awsAPITokenURL = "http://169.254.169.254/latest/api/token"
|
||||
|
||||
// awsAPITokenTTL is the default TTL to use when requesting IMDSv2 API tokens
|
||||
// -- we keep this short-lived since we get a new token with every call to readURL()
|
||||
const awsAPITokenTTL = "30"
|
||||
|
||||
// awsMetadataTokenHeader is the header that must be passed with every IMDSv2 request
|
||||
const awsMetadataTokenHeader = "X-aws-ec2-metadata-token"
|
||||
|
||||
// awsMetadataTokenTTLHeader is the header used to indicate the token TTL requested
|
||||
const awsMetadataTokenTTLHeader = "X-aws-ec2-metadata-token-ttl-seconds"
|
||||
|
||||
// awsCertificate is the certificate used to validate the instance identity
|
||||
// signature.
|
||||
const awsCertificate = `-----BEGIN CERTIFICATE-----
|
||||
|
@ -59,6 +72,8 @@ const awsSignatureAlgorithm = x509.SHA256WithRSA
|
|||
type awsConfig struct {
|
||||
identityURL string
|
||||
signatureURL string
|
||||
tokenURL string
|
||||
tokenTTL string
|
||||
certificate *x509.Certificate
|
||||
signatureAlgorithm x509.SignatureAlgorithm
|
||||
}
|
||||
|
@ -75,6 +90,8 @@ func newAWSConfig() (*awsConfig, error) {
|
|||
return &awsConfig{
|
||||
identityURL: awsIdentityURL,
|
||||
signatureURL: awsSignatureURL,
|
||||
tokenURL: awsAPITokenURL,
|
||||
tokenTTL: awsAPITokenTTL,
|
||||
certificate: cert,
|
||||
signatureAlgorithm: awsSignatureAlgorithm,
|
||||
}, nil
|
||||
|
@ -131,6 +148,7 @@ type AWS struct {
|
|||
Accounts []string `json:"accounts"`
|
||||
DisableCustomSANs bool `json:"disableCustomSANs"`
|
||||
DisableTrustOnFirstUse bool `json:"disableTrustOnFirstUse"`
|
||||
IMDSVersions []string `json:"imdsVersions"`
|
||||
InstanceAge Duration `json:"instanceAge,omitempty"`
|
||||
Claims *Claims `json:"claims,omitempty"`
|
||||
Options *Options `json:"options,omitempty"`
|
||||
|
@ -185,14 +203,14 @@ func (p *AWS) GetIdentityToken(subject, caURL string) (string, error) {
|
|||
var idoc awsInstanceIdentityDocument
|
||||
doc, err := p.readURL(p.config.identityURL)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "error retrieving identity document, are you in an AWS VM?")
|
||||
return "", errors.Wrap(err, "error retrieving identity document:\n Are you in an AWS VM?\n Is the metadata service enabled?\n Are you using the proper metadata service version?")
|
||||
}
|
||||
if err := json.Unmarshal(doc, &idoc); err != nil {
|
||||
return "", errors.Wrap(err, "error unmarshaling identity document")
|
||||
}
|
||||
sig, err := p.readURL(p.config.signatureURL)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "error retrieving identity document signature, are you in an AWS VM?")
|
||||
return "", errors.Wrap(err, "error retrieving identity document:\n Are you in an AWS VM?\n Is the metadata service enabled?\n Are you using the proper metadata service version?")
|
||||
}
|
||||
signature, err := base64.StdEncoding.DecodeString(string(sig))
|
||||
if err != nil {
|
||||
|
@ -266,6 +284,22 @@ func (p *AWS) Init(config Config) (err error) {
|
|||
return err
|
||||
}
|
||||
p.audiences = config.Audiences.WithFragment(p.GetID())
|
||||
|
||||
// validate IMDS versions
|
||||
if len(p.IMDSVersions) == 0 {
|
||||
p.IMDSVersions = []string{"v2", "v1"}
|
||||
}
|
||||
for _, v := range p.IMDSVersions {
|
||||
switch v {
|
||||
case "v1":
|
||||
// valid
|
||||
case "v2":
|
||||
// valid
|
||||
default:
|
||||
return errors.Errorf("%s: not a supported AWS Instance Metadata Service version", v)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -352,12 +386,90 @@ func (p *AWS) checkSignature(signed, signature []byte) error {
|
|||
// using pkg/errors to avoid verbose errors, the caller should use it and write
|
||||
// the appropriate error.
|
||||
func (p *AWS) readURL(url string) ([]byte, error) {
|
||||
r, err := http.Get(url)
|
||||
var resp *http.Response
|
||||
var err error
|
||||
|
||||
for _, v := range p.IMDSVersions {
|
||||
switch v {
|
||||
case "v1":
|
||||
resp, err = p.readURLv1(url)
|
||||
if err == nil && resp.StatusCode < 400 {
|
||||
return p.readResponseBody(resp)
|
||||
}
|
||||
case "v2":
|
||||
resp, err = p.readURLv2(url)
|
||||
if err == nil && resp.StatusCode < 400 {
|
||||
return p.readResponseBody(resp)
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("%s: not a supported AWS Instance Metadata Service version", v)
|
||||
}
|
||||
if resp != nil {
|
||||
resp.Body.Close()
|
||||
}
|
||||
}
|
||||
|
||||
// all versions have been exhausted and we haven't returned successfully yet so pass
|
||||
// the error on to the caller
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer r.Body.Close()
|
||||
b, err := ioutil.ReadAll(r.Body)
|
||||
return nil, fmt.Errorf("Request for metadata returned non-successful status code %d",
|
||||
resp.StatusCode)
|
||||
}
|
||||
|
||||
func (p *AWS) readURLv1(url string) (*http.Response, error) {
|
||||
client := http.Client{}
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, url, http.NoBody)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (p *AWS) readURLv2(url string) (*http.Response, error) {
|
||||
client := http.Client{}
|
||||
|
||||
// first get the token
|
||||
req, err := http.NewRequest(http.MethodPut, p.config.tokenURL, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set(awsMetadataTokenTTLHeader, p.config.tokenTTL)
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode >= 400 {
|
||||
return nil, fmt.Errorf("Request for API token returned non-successful status code %d", resp.StatusCode)
|
||||
}
|
||||
token, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// now make the request
|
||||
req, err = http.NewRequest(http.MethodGet, url, http.NoBody)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set(awsMetadataTokenHeader, string(token))
|
||||
resp, err = client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (p *AWS) readResponseBody(resp *http.Response) ([]byte, error) {
|
||||
defer resp.Body.Close()
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -104,36 +104,42 @@ func TestAWS_GetIdentityToken(t *testing.T) {
|
|||
p2.Accounts = p1.Accounts
|
||||
p2.config.identityURL = srv.URL + "/bad-document"
|
||||
p2.config.signatureURL = p1.config.signatureURL
|
||||
p2.config.tokenURL = p1.config.tokenURL
|
||||
|
||||
p3, err := generateAWS()
|
||||
assert.FatalError(t, err)
|
||||
p3.Accounts = p1.Accounts
|
||||
p3.config.signatureURL = srv.URL
|
||||
p3.config.identityURL = p1.config.identityURL
|
||||
p3.config.tokenURL = p1.config.tokenURL
|
||||
|
||||
p4, err := generateAWS()
|
||||
assert.FatalError(t, err)
|
||||
p4.Accounts = p1.Accounts
|
||||
p4.config.signatureURL = srv.URL + "/bad-signature"
|
||||
p4.config.identityURL = p1.config.identityURL
|
||||
p4.config.tokenURL = p1.config.tokenURL
|
||||
|
||||
p5, err := generateAWS()
|
||||
assert.FatalError(t, err)
|
||||
p5.Accounts = p1.Accounts
|
||||
p5.config.identityURL = "https://1234.1234.1234.1234"
|
||||
p5.config.signatureURL = p1.config.signatureURL
|
||||
p5.config.tokenURL = p1.config.tokenURL
|
||||
|
||||
p6, err := generateAWS()
|
||||
assert.FatalError(t, err)
|
||||
p6.Accounts = p1.Accounts
|
||||
p6.config.identityURL = p1.config.identityURL
|
||||
p6.config.signatureURL = "https://1234.1234.1234.1234"
|
||||
p6.config.tokenURL = p1.config.tokenURL
|
||||
|
||||
p7, err := generateAWS()
|
||||
assert.FatalError(t, err)
|
||||
p7.Accounts = p1.Accounts
|
||||
p7.config.identityURL = srv.URL + "/bad-json"
|
||||
p7.config.signatureURL = p1.config.signatureURL
|
||||
p7.config.tokenURL = p1.config.tokenURL
|
||||
|
||||
caURL := "https://ca.smallstep.com"
|
||||
u, err := url.Parse(caURL)
|
||||
|
@ -181,6 +187,49 @@ func TestAWS_GetIdentityToken(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestAWS_GetIdentityToken_V1Only(t *testing.T) {
|
||||
aws, srv, err := generateAWSWithServerV1Only()
|
||||
assert.FatalError(t, err)
|
||||
defer srv.Close()
|
||||
|
||||
subject := "foo.local"
|
||||
caURL := "https://ca.smallstep.com"
|
||||
u, err := url.Parse(caURL)
|
||||
assert.Nil(t, err)
|
||||
|
||||
token, err := aws.GetIdentityToken(subject, caURL)
|
||||
assert.Nil(t, err)
|
||||
|
||||
_, c, err := parseAWSToken(token)
|
||||
if assert.NoError(t, err) {
|
||||
assert.Equals(t, awsIssuer, c.Issuer)
|
||||
assert.Equals(t, subject, c.Subject)
|
||||
assert.Equals(t, jose.Audience{u.ResolveReference(&url.URL{Path: "/1.0/sign", Fragment: aws.GetID()}).String()}, c.Audience)
|
||||
assert.Equals(t, aws.Accounts[0], c.document.AccountID)
|
||||
err = aws.config.certificate.CheckSignature(
|
||||
aws.config.signatureAlgorithm, c.Amazon.Document, c.Amazon.Signature)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAWS_GetIdentityToken_BadIDMS(t *testing.T) {
|
||||
aws, srv, err := generateAWSWithServer()
|
||||
|
||||
aws.IMDSVersions = []string{"bad"}
|
||||
|
||||
assert.FatalError(t, err)
|
||||
defer srv.Close()
|
||||
|
||||
subject := "foo.local"
|
||||
caURL := "https://ca.smallstep.com"
|
||||
|
||||
token, err := aws.GetIdentityToken(subject, caURL)
|
||||
assert.Equals(t, token, "")
|
||||
|
||||
badIDMS := errors.New("bad: not a supported AWS Instance Metadata Service version")
|
||||
assert.HasSuffix(t, err.Error(), badIDMS.Error())
|
||||
}
|
||||
|
||||
func TestAWS_Init(t *testing.T) {
|
||||
config := Config{
|
||||
Claims: globalProvisionerClaims,
|
||||
|
@ -197,6 +246,7 @@ func TestAWS_Init(t *testing.T) {
|
|||
DisableCustomSANs bool
|
||||
DisableTrustOnFirstUse bool
|
||||
InstanceAge Duration
|
||||
IMDSVersions []string
|
||||
Claims *Claims
|
||||
}
|
||||
type args struct {
|
||||
|
@ -208,12 +258,16 @@ func TestAWS_Init(t *testing.T) {
|
|||
args args
|
||||
wantErr bool
|
||||
}{
|
||||
{"ok", fields{"AWS", "name", []string{"account"}, false, false, zero, nil}, args{config}, false},
|
||||
{"ok", fields{"AWS", "name", []string{"account"}, true, true, Duration{Duration: 1 * time.Minute}, nil}, args{config}, false},
|
||||
{"fail type ", fields{"", "name", []string{"account"}, false, false, zero, nil}, args{config}, true},
|
||||
{"fail name", fields{"AWS", "", []string{"account"}, false, false, zero, nil}, args{config}, true},
|
||||
{"bad instance age", fields{"AWS", "name", []string{"account"}, false, false, Duration{Duration: -1 * time.Minute}, nil}, args{config}, true},
|
||||
{"fail claims", fields{"AWS", "name", []string{"account"}, false, false, zero, badClaims}, args{config}, true},
|
||||
{"ok", fields{"AWS", "name", []string{"account"}, false, false, zero, []string{"v1", "v2"}, nil}, args{config}, false},
|
||||
{"ok/v1", fields{"AWS", "name", []string{"account"}, false, false, zero, []string{"v1"}, nil}, args{config}, false},
|
||||
{"ok/v2", fields{"AWS", "name", []string{"account"}, false, false, zero, []string{"v2"}, nil}, args{config}, false},
|
||||
{"ok/empty", fields{"AWS", "name", []string{"account"}, false, false, zero, []string{}, nil}, args{config}, false},
|
||||
{"ok/duration", fields{"AWS", "name", []string{"account"}, true, true, Duration{Duration: 1 * time.Minute}, []string{"v1", "v2"}, nil}, args{config}, false},
|
||||
{"fail type ", fields{"", "name", []string{"account"}, false, false, zero, []string{"v1", "v2"}, nil}, args{config}, true},
|
||||
{"fail name", fields{"AWS", "", []string{"account"}, false, false, zero, []string{"v1", "v2"}, nil}, args{config}, true},
|
||||
{"bad instance age", fields{"AWS", "name", []string{"account"}, false, false, Duration{Duration: -1 * time.Minute}, []string{"v1", "v2"}, nil}, args{config}, true},
|
||||
{"fail/imds", fields{"AWS", "name", []string{"account"}, false, false, zero, []string{"bad"}, nil}, args{config}, true},
|
||||
{"fail claims", fields{"AWS", "name", []string{"account"}, false, false, zero, []string{"v1", "v2"}, badClaims}, args{config}, true},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
@ -224,6 +278,7 @@ func TestAWS_Init(t *testing.T) {
|
|||
DisableCustomSANs: tt.fields.DisableCustomSANs,
|
||||
DisableTrustOnFirstUse: tt.fields.DisableTrustOnFirstUse,
|
||||
InstanceAge: tt.fields.InstanceAge,
|
||||
IMDSVersions: tt.fields.IMDSVersions,
|
||||
Claims: tt.fields.Claims,
|
||||
}
|
||||
if err := p.Init(tt.args.config); (err != nil) != tt.wantErr {
|
||||
|
|
|
@ -408,14 +408,17 @@ func generateAWS() (*AWS, error) {
|
|||
return nil, errors.Wrap(err, "error parsing AWS certificate")
|
||||
}
|
||||
return &AWS{
|
||||
Type: "AWS",
|
||||
Name: name,
|
||||
Accounts: []string{accountID},
|
||||
Claims: &globalProvisionerClaims,
|
||||
claimer: claimer,
|
||||
Type: "AWS",
|
||||
Name: name,
|
||||
Accounts: []string{accountID},
|
||||
Claims: &globalProvisionerClaims,
|
||||
IMDSVersions: []string{"v2", "v1"},
|
||||
claimer: claimer,
|
||||
config: &awsConfig{
|
||||
identityURL: awsIdentityURL,
|
||||
signatureURL: awsSignatureURL,
|
||||
tokenURL: awsAPITokenURL,
|
||||
tokenTTL: awsAPITokenTTL,
|
||||
certificate: cert,
|
||||
signatureAlgorithm: awsSignatureAlgorithm,
|
||||
},
|
||||
|
@ -452,6 +455,115 @@ func generateAWSWithServer() (*AWS, *httptest.Server, error) {
|
|||
return nil, nil, err
|
||||
}
|
||||
|
||||
sum := sha256.Sum256(doc)
|
||||
signature, err := key.Sign(rand.Reader, sum[:], crypto.SHA256)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "error signing document")
|
||||
}
|
||||
token := "AQAEAEEO9-7Z88ewKFpboZuDlFYWz9A3AN-wMOVzjEhfAyXW31BvVw=="
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case "/latest/dynamic/instance-identity/document":
|
||||
// check for API token
|
||||
if r.Header.Get("X-aws-ec2-metadata-token") != token {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte("401 Unauthorized"))
|
||||
}
|
||||
w.Write(doc)
|
||||
case "/latest/dynamic/instance-identity/signature":
|
||||
// check for API token
|
||||
if r.Header.Get("X-aws-ec2-metadata-token") != token {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte("401 Unauthorized"))
|
||||
}
|
||||
w.Write([]byte(base64.StdEncoding.EncodeToString(signature)))
|
||||
case "/latest/api/token":
|
||||
w.Write([]byte(token))
|
||||
case "/bad-document":
|
||||
w.Write([]byte("{}"))
|
||||
case "/bad-signature":
|
||||
w.Write([]byte("YmFkLXNpZ25hdHVyZQo="))
|
||||
case "/bad-json":
|
||||
w.Write([]byte("{"))
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
}))
|
||||
aws.config.identityURL = srv.URL + "/latest/dynamic/instance-identity/document"
|
||||
aws.config.signatureURL = srv.URL + "/latest/dynamic/instance-identity/signature"
|
||||
aws.config.tokenURL = srv.URL + "/latest/api/token"
|
||||
return aws, srv, nil
|
||||
}
|
||||
|
||||
func generateAWSV1Only() (*AWS, error) {
|
||||
name, err := randutil.Alphanumeric(10)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
accountID, err := randutil.Alphanumeric(10)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
claimer, err := NewClaimer(nil, globalProvisionerClaims)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
block, _ := pem.Decode([]byte(awsTestCertificate))
|
||||
if block == nil || block.Type != "CERTIFICATE" {
|
||||
return nil, errors.New("error decoding AWS certificate")
|
||||
}
|
||||
cert, err := x509.ParseCertificate(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error parsing AWS certificate")
|
||||
}
|
||||
return &AWS{
|
||||
Type: "AWS",
|
||||
Name: name,
|
||||
Accounts: []string{accountID},
|
||||
Claims: &globalProvisionerClaims,
|
||||
IMDSVersions: []string{"v1"},
|
||||
claimer: claimer,
|
||||
config: &awsConfig{
|
||||
identityURL: awsIdentityURL,
|
||||
signatureURL: awsSignatureURL,
|
||||
tokenURL: awsAPITokenURL,
|
||||
tokenTTL: awsAPITokenTTL,
|
||||
certificate: cert,
|
||||
signatureAlgorithm: awsSignatureAlgorithm,
|
||||
},
|
||||
audiences: testAudiences.WithFragment("aws/" + name),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func generateAWSWithServerV1Only() (*AWS, *httptest.Server, error) {
|
||||
aws, err := generateAWSV1Only()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
block, _ := pem.Decode([]byte(awsTestKey))
|
||||
if block == nil || block.Type != "RSA PRIVATE KEY" {
|
||||
return nil, nil, errors.New("error decoding AWS key")
|
||||
}
|
||||
key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "error parsing AWS private key")
|
||||
}
|
||||
doc, err := json.MarshalIndent(awsInstanceIdentityDocument{
|
||||
AccountID: aws.Accounts[0],
|
||||
Architecture: "x86_64",
|
||||
AvailabilityZone: "us-west-2b",
|
||||
ImageID: "image-id",
|
||||
InstanceID: "instance-id",
|
||||
InstanceType: "t2.micro",
|
||||
PendingTime: time.Now(),
|
||||
PrivateIP: "127.0.0.1",
|
||||
Region: "us-west-1",
|
||||
Version: "2017-09-30",
|
||||
}, "", " ")
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
sum := sha256.Sum256(doc)
|
||||
signature, err := key.Sign(rand.Reader, sum[:], crypto.SHA256)
|
||||
if err != nil {
|
||||
|
|
|
@ -718,6 +718,11 @@ A few things to consider / implement when running multiple instances of `step-ca
|
|||
* Use `MySQL` DB: The default `Badger` DB cannot be read / written by more than one
|
||||
process simultaneously. The only supported DB that can support multiple instances
|
||||
is `MySQL`. See the [database documentation][4] for guidance on configuring `MySQL`.
|
||||
* The ACME server has known concurrency limitations when using the same account to
|
||||
manage multiple orders. The recommended temporary workaround is to generate
|
||||
an ephemeral account keypair for each new ACME order, or to ensure that ACME
|
||||
orders owned by the same account are managed serially. The issue tracking
|
||||
this limitation can be found [here](https://github.com/smallstep/certificates/issues/341).
|
||||
|
||||
* Synchronize `ca.json` across instances: `step-ca` reads all of it's
|
||||
configuration (and all of the provisioner configuration) from the `ca.json` file
|
||||
|
|
4
go.mod
4
go.mod
|
@ -13,8 +13,8 @@ require (
|
|||
github.com/pkg/errors v0.9.1
|
||||
github.com/rs/xid v1.2.1
|
||||
github.com/sirupsen/logrus v1.4.2
|
||||
github.com/smallstep/assert v0.0.0-20200103212524-b99dc1097b15
|
||||
github.com/smallstep/cli v0.14.7-rc.1.0.20200721180458-731b7c4c8c95
|
||||
github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262
|
||||
github.com/smallstep/cli v0.14.7-rc.1.0.20200727165646-eb4e97335f2d
|
||||
github.com/smallstep/nosql v0.3.0
|
||||
github.com/urfave/cli v1.22.2
|
||||
go.step.sm/crypto v0.0.0-20200805202904-ec18b6df3cf0
|
||||
|
|
53
go.sum
53
go.sum
|
@ -476,11 +476,13 @@ github.com/smallstep/assert v0.0.0-20180720014142-de77670473b5 h1:lX6ybsQW9Agn3q
|
|||
github.com/smallstep/assert v0.0.0-20180720014142-de77670473b5/go.mod h1:TC9A4+RjIOS+HyTH7wG17/gSqVv95uDw2J64dQZx7RE=
|
||||
github.com/smallstep/assert v0.0.0-20200103212524-b99dc1097b15 h1:kSImCuenAkXtCaBeQ1UhmzzJGRhSm8sVH7I3sHE2Qdg=
|
||||
github.com/smallstep/assert v0.0.0-20200103212524-b99dc1097b15/go.mod h1:MyOHs9Po2fbM1LHej6sBUT8ozbxmMOFG+E+rx/GSGuc=
|
||||
github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262 h1:unQFBIznI+VYD1/1fApl1A+9VcBk+9dcqGfnePY87LY=
|
||||
github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262/go.mod h1:MyOHs9Po2fbM1LHej6sBUT8ozbxmMOFG+E+rx/GSGuc=
|
||||
github.com/smallstep/certificates v0.14.5/go.mod h1:zzpB8wMz967gL8FmK6zvCNB4pDVwFDKjPg1diTVc1h8=
|
||||
github.com/smallstep/certinfo v1.3.0/go.mod h1:1gQJekdPwPvUwFWGTi7bZELmQT09cxC9wJ0VBkBNiwU=
|
||||
github.com/smallstep/cli v0.14.5/go.mod h1:mRFuqC3cGwQESBGJvog4o76jZZZ7bMjkE+hAnq2QyR8=
|
||||
github.com/smallstep/cli v0.14.7-rc.1.0.20200721180458-731b7c4c8c95 h1:TcCYqEqh6EIEiFabRdtG0IGyFK01kRLTjx6TIKqjxX8=
|
||||
github.com/smallstep/cli v0.14.7-rc.1.0.20200721180458-731b7c4c8c95/go.mod h1:7aWHk7WwJMpEP4PYyav86FMpaI9vuA0uJRliUAqCwxg=
|
||||
github.com/smallstep/cli v0.14.7-rc.1.0.20200727165646-eb4e97335f2d h1:bDnvzyEXzAMO5in8QHRrQCEUopiXjFVKHiR8c0m7Iww=
|
||||
github.com/smallstep/cli v0.14.7-rc.1.0.20200727165646-eb4e97335f2d/go.mod h1:7aWHk7WwJMpEP4PYyav86FMpaI9vuA0uJRliUAqCwxg=
|
||||
github.com/smallstep/nosql v0.3.0 h1:V1X5vfDsDt89499h3jZFUlR4VnnsYYs5tXaQZ0w8z5U=
|
||||
github.com/smallstep/nosql v0.3.0/go.mod h1:QG7gNOpidifn99MjZaiNbm7HPesIyBd97F/OfacNz8Q=
|
||||
github.com/smallstep/truststore v0.9.3/go.mod h1:PRSkpRIhAYBK/KLWkHNgRdYgzWMEy45bN7PSJCfKKGE=
|
||||
|
@ -489,69 +491,51 @@ github.com/smallstep/zcrypto v0.0.0-20200203191936-fbc32cf76bce/go.mod h1:+F24VU
|
|||
github.com/smallstep/zlint v0.0.0-20180727184541-d84eaafe274f/go.mod h1:GeHHT7sJDI9ti3oEaFnvx1F4N8n3ZSw2YM1+sbEoxc4=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/sourcegraph/go-diff v0.5.1 h1:gO6i5zugwzo1RVTvgvfwCOSVegNuvnNi6bAD1QCmkHs=
|
||||
github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.1.0/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
|
||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg=
|
||||
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
|
||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.2/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.0.2/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM=
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/spf13/viper v1.6.1 h1:VPZzIkznI1YhVMRi6vNFLHSwhnhReBfgTxIPccpfdZk=
|
||||
github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/timakin/bodyclose v0.0.0-20190721030226-87058b9bfcec/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=
|
||||
github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e h1:RumXZ56IrCj4CL+g1b9OL/oH0QnsF976bC8xQFYUD5Q=
|
||||
github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4=
|
||||
github.com/tommy-muehle/go-mnd v1.1.1 h1:4D0wuPKjOTiK2garzuPGGvm4zZ/wLYDOH8TJSABC7KU=
|
||||
github.com/tommy-muehle/go-mnd v1.1.1/go.mod h1:dSUh0FtTP8VhvkL1S+gUR1OKd9ZnSaozuI6r3m6wOig=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/ultraware/funlen v0.0.1/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA=
|
||||
github.com/ultraware/funlen v0.0.2 h1:Av96YVBwwNSe4MLR7iI/BIa3VyI7/djnto/pK3Uxbdo=
|
||||
github.com/ultraware/funlen v0.0.2/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA=
|
||||
github.com/ultraware/whitespace v0.0.4 h1:If7Va4cM03mpgrNH9k49/VOicWpGoG70XPBFFODYDsg=
|
||||
github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo=
|
||||
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/uudashr/gocognit v1.0.1 h1:MoG2fZ0b/Eo7NXoIwCVFLG5JED3qgQz5/NEE+rOsjPs=
|
||||
github.com/uudashr/gocognit v1.0.1/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s=
|
||||
|
@ -559,7 +543,6 @@ github.com/valyala/quicktemplate v1.1.1/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOV
|
|||
github.com/valyala/quicktemplate v1.2.0/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4=
|
||||
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
|
||||
github.com/weppos/publicsuffix-go v0.4.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/zmap/rc2 v0.0.0-20131011165748-24b9757f5521/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE=
|
||||
|
@ -571,7 +554,6 @@ github.com/zmap/zlint v0.0.0-20190516161541-9047d02cf65a/go.mod h1:xwLbce0UzBXp4
|
|||
go.etcd.io/bbolt v1.3.2 h1:Z/90sZLPOeCy2PwprqkFa25PdkusRzaj9P8zm/KNyvk=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/etcd v3.3.13+incompatible/go.mod h1:yaeTdrJi5lOmYerz05bd8+V7KubZs8YSFZfzsF9A6aI=
|
||||
go.etcd.io/etcd v3.3.18+incompatible h1:5aomL5mqoKHxw6NG+oYgsowk8tU8aOalo2IdZxdWHkw=
|
||||
go.etcd.io/etcd v3.3.18+incompatible/go.mod h1:yaeTdrJi5lOmYerz05bd8+V7KubZs8YSFZfzsF9A6aI=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
|
@ -581,16 +563,12 @@ go.step.sm/crypto v0.0.0-20200805202904-ec18b6df3cf0 h1:FymMl8TrXGxFf80BWpO0CnkS
|
|||
go.step.sm/crypto v0.0.0-20200805202904-ec18b6df3cf0/go.mod h1:8VYxmvSKt5yOTBx3MGsD2Gk4F1Es/3FIxrjnfeYWE8U=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.5.1 h1:rsqfU5vBkVknbhUGbAUwQKR2H4ItV8tjJ+6kJX4cxHM=
|
||||
go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/multierr v1.4.0 h1:f3WCSC2KzAcBXGATIxAB1E2XuCpNU255wNKZ505qi3E=
|
||||
go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.13.0 h1:nR6NoDBgAf67s68NhaXbsojM+2gxp3S1hWkHDl27pVU=
|
||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
|
@ -598,14 +576,10 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
|||
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7 h1:0hQKqeLdqlt5iIwVOBErRisrHJAN57yOiPRQItI20fU=
|
||||
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876 h1:sKJQZMuxjOAR/Uo2LBfU90onWEf1dF4C+0hPJCc9Mpc=
|
||||
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59 h1:3zb4D3T4G8jdExgVU/95+vQXfpEPiMdCaZgmGVxjNHM=
|
||||
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904 h1:bXoxMPcSLOq08zI3/c5dEBT6lE4eh+jOh886GHrn6V8=
|
||||
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
|
@ -623,7 +597,6 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl
|
|||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f h1:J5lckAjkw6qYlOZNj90mLYNTEKDvWeuc1yieZ8qUzUE=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
|
@ -647,11 +620,9 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn
|
|||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
|
@ -666,7 +637,6 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
|
|||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20171026204733-164713f0dfce/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180202135801-37707fdb30a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
@ -679,7 +649,6 @@ golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -688,7 +657,6 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -696,14 +664,12 @@ golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e h1:LwyF2AFISC9nVbS6MgzsaQNSUsRXI49GS+YQ5KX/QH0=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20170915090833-1cbadb444a80/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20170915040203-e531a2a1c15f/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
@ -743,7 +709,6 @@ golang.org/x/tools v0.0.0-20191113232020-e2727e816f5a/go.mod h1:b+2E5dAYhXwXZwtn
|
|||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200106190116-7be0a674c9fc h1:MR2F33ipDGog0C4eMhU6u9o3q6c3dvYis2aG6Jl12Wg=
|
||||
golang.org/x/tools v0.0.0-20200106190116-7be0a674c9fc/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
@ -757,7 +722,6 @@ google.golang.org/api v0.15.0 h1:yzlyyDW/J0w8yNFJIhiAJy4kq74S+1DOLdawELNxFMA=
|
|||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
|
||||
|
@ -788,13 +752,11 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
|
|||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.28 h1:n1tBJnnK2r7g9OW2btFH91V92STTUevLXYFb8gy9EMk=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
|
||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.51.1 h1:GyboHr4UqMiLUybYjd22ZjQIKEJEpgtLXtuGbR21Oho=
|
||||
gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/square/go-jose.v2 v2.4.0 h1:0kXPskUMGAXXWJlP05ktEMOV0vmzFQUWw6d+aZJQU8A=
|
||||
|
@ -802,7 +764,6 @@ gopkg.in/square/go-jose.v2 v2.4.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76
|
|||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
@ -813,21 +774,15 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh
|
|||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0=
|
||||
howett.net/plist v0.0.0-20200419221736-3b63eb3a43b5/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0=
|
||||
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I=
|
||||
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
|
||||
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo=
|
||||
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
|
||||
mvdan.cc/unparam v0.0.0-20190209190245-fbb59629db34/go.mod h1:H6SUd1XjIs+qQCyskXg5OFSrilMRUkD8ePJpHKDPaeY=
|
||||
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
|
||||
mvdan.cc/unparam v0.0.0-20191111180625-960b1ec0f2c2 h1:K7wru2CfJGumS5hkiguQ0Rb9ebKM2Jo8s5d4Jm9lFaM=
|
||||
mvdan.cc/unparam v0.0.0-20191111180625-960b1ec0f2c2/go.mod h1:rCqoQrfAmpTX/h2APczwM7UymU/uvaOluiVPIYCSY/k=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
|
||||
sourcegraph.com/sqs/pbtypes v1.0.0 h1:f7lAwqviDEGvON4kRv0o5V7FT/IQK+tbkF664XMbP3o=
|
||||
sourcegraph.com/sqs/pbtypes v1.0.0/go.mod h1:3AciMUv4qUuRHRHhOG4TZOB+72GdPVz5k+c648qsFS4=
|
||||
|
|
82
make/docker.mk
Normal file
82
make/docker.mk
Normal file
|
@ -0,0 +1,82 @@
|
|||
#########################################
|
||||
# Building Docker Image
|
||||
#
|
||||
# This uses a multi-stage build file. The first stage is a builder (that might
|
||||
# be large in size). After the build has succeeded, the statically linked
|
||||
# binary is copied to a new image that is optimized for size.
|
||||
#########################################
|
||||
|
||||
docker-prepare:
|
||||
# Ensure, we can build for ARM architecture
|
||||
[ -f /proc/sys/fs/binfmt_misc/qemu-arm ] || docker run --rm --privileged docker/binfmt:a7996909642ee92942dcd6cff44b9b95f08dad64
|
||||
|
||||
# Register buildx builder
|
||||
mkdir -p $$HOME/.docker/cli-plugins
|
||||
|
||||
wget -O $$HOME/.docker/cli-plugins/docker-buildx https://github.com/docker/buildx/releases/download/v0.3.1/buildx-v0.3.1.linux-amd64
|
||||
chmod +x $$HOME/.docker/cli-plugins/docker-buildx
|
||||
|
||||
$$HOME/.docker/cli-plugins/docker-buildx create --name mybuilder --platform amd64 --platform arm || true
|
||||
$$HOME/.docker/cli-plugins/docker-buildx use mybuilder
|
||||
|
||||
.PHONY: docker-prepare
|
||||
|
||||
#################################################
|
||||
# Releasing Docker Images
|
||||
#
|
||||
# Using the docker build infrastructure, this section is responsible for
|
||||
# logging into docker hub.
|
||||
#################################################
|
||||
|
||||
# Rely on DOCKER_USERNAME and DOCKER_PASSWORD being set inside the CI or
|
||||
# equivalent environment
|
||||
docker-login:
|
||||
$Q docker login -u="$(DOCKER_USERNAME)" -p="$(DOCKER_PASSWORD)"
|
||||
|
||||
.PHONY: docker-login
|
||||
|
||||
#################################################
|
||||
# Targets for different type of builds
|
||||
#################################################
|
||||
|
||||
DOCKER_IMAGE_NAME = smallstep/step-ca
|
||||
PLATFORMS = --platform amd64 --platform 386 --platform arm --platform arm64
|
||||
|
||||
define DOCKER_BUILDX
|
||||
# $(1) -- Image Tag
|
||||
# $(2) -- Push (empty is no push | --push will push to dockerhub)
|
||||
$$HOME/.docker/cli-plugins/docker-buildx build . --progress plain -t $(DOCKER_IMAGE_NAME):$(1) -f docker/Dockerfile.step-ca $(PLATFORMS) $(2)
|
||||
endef
|
||||
|
||||
# For non-master builds don't build the docker containers.
|
||||
docker-branch:
|
||||
|
||||
# For master builds create the docker containers but don't push them.
|
||||
docker-master: docker-prepare
|
||||
$(call DOCKER_BUILDX,latest,)
|
||||
|
||||
# For all builds with a release candidate tag build and push the containers.
|
||||
docker-release-candidate: docker-prepare docker-login
|
||||
$(call DOCKER_BUILDX,$(VERSION),--push)
|
||||
|
||||
# For all builds with a release tag build and push the containers.
|
||||
docker-release: docker-prepare docker-login
|
||||
$(call DOCKER_BUILDX,latest,--push)
|
||||
$(call DOCKER_BUILDX,$(VERSION),--push)
|
||||
|
||||
.PHONY: docker-branch docker-master docker-release-candidate docker-release
|
||||
|
||||
# XXX We put the output for the build in 'output' so we don't mess with how we
|
||||
# do rule overriding from the base Makefile (if you name it 'build' it messes up
|
||||
# the wildcarding).
|
||||
DOCKER_OUTPUT=$(OUTPUT_ROOT)docker/
|
||||
|
||||
DOCKER_MAKE=V=$V GOOS_OVERRIDE='GOOS=linux GOARCH=amd64' PREFIX=$(1) make $(1)bin/$(BINNAME)
|
||||
DOCKER_BUILD=$Q docker build -t $(DOCKER_IMAGE_NAME):latest -f docker/Dockerfile.step-ca --build-arg BINPATH=$(DOCKER_OUTPUT)bin/$(BINNAME) .
|
||||
|
||||
docker-dev: docker/Dockerfile.step-ca
|
||||
mkdir -p $(DOCKER_OUTPUT)
|
||||
$(call DOCKER_MAKE,$(DOCKER_OUTPUT),step-ca)
|
||||
$(call DOCKER_BUILD)
|
||||
|
||||
.PHONY: docker-dev
|
10
pki/pki.go
10
pki/pki.go
|
@ -446,9 +446,19 @@ func (p *PKI) GenerateConfig(opt ...Option) (*authority.Config, error) {
|
|||
HostKey: p.sshHostKey,
|
||||
UserKey: p.sshUserKey,
|
||||
}
|
||||
// Enable SSH authorization for default JWK provisioner
|
||||
prov.Claims = &provisioner.Claims{
|
||||
EnableSSHCA: &enableSSHCA,
|
||||
}
|
||||
// Add default SSHPOP provisioner
|
||||
sshpop := &provisioner.SSHPOP{
|
||||
Type: "SSHPOP",
|
||||
Name: "sshpop",
|
||||
Claims: &provisioner.Claims{
|
||||
EnableSSHCA: &enableSSHCA,
|
||||
},
|
||||
}
|
||||
config.AuthorityConfig.Provisioners = append(config.AuthorityConfig.Provisioners, sshpop)
|
||||
}
|
||||
|
||||
// Apply configuration modifiers
|
||||
|
|
Loading…
Reference in a new issue