1
0
mirror of https://github.com/smallstep/cli.git synced 2025-08-07 16:02:54 +03:00

Admin workflow CLI v1

This commit is contained in:
max furman
2021-05-06 17:02:49 -07:00
parent 74aef56439
commit cce2ea8ef2
32 changed files with 2851 additions and 105 deletions

View File

@@ -8,7 +8,7 @@ linters-settings:
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf
golint:
revive:
min-confidence: 0
gocyclo:
min-complexity: 10
@@ -44,7 +44,7 @@ linters:
disable-all: true
enable:
- gofmt
- golint
- revive
- govet
- misspell
- ineffassign

View File

@@ -21,6 +21,7 @@ import (
// Enabled commands
_ "github.com/smallstep/cli/command/base64"
_ "github.com/smallstep/cli/command/beta"
_ "github.com/smallstep/cli/command/ca"
_ "github.com/smallstep/cli/command/certificate"
_ "github.com/smallstep/cli/command/crypto"

23
command/beta/beta.go Normal file
View File

@@ -0,0 +1,23 @@
package beta
import (
"github.com/smallstep/cli/command"
"github.com/smallstep/cli/command/ca"
"github.com/urfave/cli"
)
// init creates and registers the ca command
func init() {
cmd := cli.Command{
Name: "beta",
Usage: "commands that are being tested; these APIs are likely to change",
UsageText: "step beta <subcommand> [arguments] [global-flags] [subcommand-flags]",
Description: `**step beta** command group provides access to new APIs that are in development.
`,
Subcommands: cli.Commands{
ca.BetaCommand(),
},
}
command.Register(cmd)
}

101
command/ca/admin/add.go Normal file
View File

@@ -0,0 +1,101 @@
package admin
import (
"fmt"
"os"
"text/tabwriter"
adminAPI "github.com/smallstep/certificates/authority/admin/api"
"github.com/smallstep/cli/errs"
"github.com/smallstep/cli/flags"
"github.com/smallstep/cli/utils/cautils"
"github.com/urfave/cli"
"go.step.sm/linkedca"
)
func addCommand() cli.Command {
return cli.Command{
Name: "add",
Action: cli.ActionFunc(addAction),
Usage: "add an admin to the CA configuration",
UsageText: `**step beta ca admin add** <subject> <provisioner> [**--super**]`,
Flags: []cli.Flag{
cli.BoolFlag{
Name: "super",
Usage: `Give administrator SuperAdmin privileges.`,
},
flags.AdminCert,
flags.AdminKey,
flags.AdminProvisioner,
flags.AdminSubject,
flags.PasswordFile,
flags.CaURL,
flags.Root,
},
Description: `**step beta ca admin add** adds an admin to the CA configuration.
## POSITIONAL ARGUMENTS
<subject>
: The subject name that must appear in the identifying credential of the admin.
<provisioner>
: The name of the provisioner
## EXAMPLES
Add regular Admin:
'''
$ step beta ca admin add max@smallstep.com google
'''
Add SuperAdmin:
'''
$ step beta ca admin add max@smallstep.com google --super
'''
`,
}
}
func addAction(ctx *cli.Context) (err error) {
if err := errs.NumberOfArguments(ctx, 2); err != nil {
return err
}
args := ctx.Args()
subject := args.Get(0)
provName := args.Get(1)
typ := linkedca.Admin_ADMIN
if ctx.Bool("super") {
typ = linkedca.Admin_SUPER_ADMIN
}
client, err := cautils.NewAdminClient(ctx)
if err != nil {
return err
}
adm, err := client.CreateAdmin(&adminAPI.CreateAdminRequest{
Subject: subject,
Provisioner: provName,
Type: typ,
})
if err != nil {
return err
}
cliAdm, err := toCLI(ctx, client, adm)
if err != nil {
return err
}
w := new(tabwriter.Writer)
// Format in tab-separated columns with a tab stop of 8.
w.Init(os.Stdout, 0, 8, 1, '\t', 0)
fmt.Fprintln(w, "SUBJECT\tPROVISIONER\tTYPE")
fmt.Fprintf(w, "%s\t%s (%s)\t%s\n", cliAdm.Subject, cliAdm.ProvisionerName, cliAdm.ProvisionerType, adm.Type.String())
w.Flush()
return nil
}

154
command/ca/admin/admin.go Normal file
View File

@@ -0,0 +1,154 @@
package admin
import (
"errors"
"fmt"
"github.com/smallstep/certificates/ca"
"github.com/smallstep/cli/errs"
"github.com/smallstep/cli/ui"
"github.com/urfave/cli"
"go.step.sm/linkedca"
)
// Command returns the jwk subcommand.
func Command() cli.Command {
return cli.Command{
Name: "admin",
Usage: "create and manage the certificate authority admins",
UsageText: "step beta ca admin <subcommand> [arguments] [global-flags] [subcommand-flags]",
Subcommands: cli.Commands{
listCommand(),
addCommand(),
removeCommand(),
updateCommand(),
},
Description: `The **step ca admin** command group provides facilities for managing the
certificate authority admins.
A admin is an entity that manages administrative resources within a certificate
authority. Admins manage
* certificate authority configuration
* provisioner configuration
* other admins and admin privileges
## EXAMPLES
List the active admins:
'''
$ step beta ca admin list
'''
Add an admin:
'''
$ step beta ca admin add max@smallstep.com my-jwk-provisioner
'''
Remove an admin:
'''
$ step beta ca admin remove max@smallstep.com
'''`,
}
}
type adminSelect struct {
Name string
CLIAdmin *cliAdmin
}
type cliAdmin struct {
*linkedca.Admin
ProvisionerName string
ProvisionerType string
}
func toCLI(ctx *cli.Context, client *ca.AdminClient, adm *linkedca.Admin) (*cliAdmin, error) {
p, err := client.GetProvisioner(ca.WithProvisionerID(adm.ProvisionerId))
if err != nil {
return nil, err
}
return &cliAdmin{Admin: adm, ProvisionerName: p.GetName(), ProvisionerType: p.GetType().String()}, nil
}
func listToCLI(ctx *cli.Context, client *ca.AdminClient, admins []*linkedca.Admin) ([]*cliAdmin, error) {
var (
err error
cliAdmins = make([]*cliAdmin, len(admins))
)
for i, adm := range admins {
cliAdmins[i], err = toCLI(ctx, client, adm)
if err != nil {
return nil, err
}
}
return cliAdmins, nil
}
func adminPrompt(ctx *cli.Context, client *ca.AdminClient, admins []*linkedca.Admin) (*cliAdmin, error) {
if len(admins) == 0 {
return nil, errors.New("no admins to update")
}
args := ctx.Args()
subject := args[0]
cliAdmins, err := listToCLI(ctx, client, admins)
if err != nil {
return nil, err
}
// Filter by subject
cliAdmins = adminFilter(cliAdmins, func(adm *cliAdmin) bool {
return adm.Subject == subject
})
if len(cliAdmins) == 0 {
return nil, fmt.Errorf("no admins with subject %s", subject)
}
// Filter by provisionerName
if provName := ctx.String("provisioner"); len(provName) != 0 {
cliAdmins = adminFilter(cliAdmins, func(a *cliAdmin) bool {
return a.ProvisionerName == provName
})
if len(cliAdmins) == 0 {
return nil, errs.InvalidFlagValue(ctx, "provisioner", provName, "")
}
}
// Select admin
var items []*adminSelect
for _, adm := range cliAdmins {
items = append(items, &adminSelect{
//Name: fmt.Sprintf("%s\t%s (%s)\t%s", adm.Subject,
Name: fmt.Sprintf("subject: %s, provisioner: %s(%s), type: %s", adm.Subject,
adm.ProvisionerName, adm.ProvisionerType, adm.Type),
CLIAdmin: adm,
})
}
if len(items) == 1 {
if err := ui.PrintSelected("Admin", items[0].Name); err != nil {
return nil, err
}
return items[0].CLIAdmin, nil
}
i, _, err := ui.Select("Select an admin:", items,
ui.WithSelectTemplates(ui.NamedSelectTemplates("Admin")))
if err != nil {
return nil, err
}
return items[i].CLIAdmin, nil
}
// adminFilter returns a slice of admins that pass the given filter.
func adminFilter(cliAdmins []*cliAdmin, f func(*cliAdmin) bool) []*cliAdmin {
var result []*cliAdmin
for _, a := range cliAdmins {
if f(a) {
result = append(result, a)
}
}
return result
}

116
command/ca/admin/list.go Normal file
View File

@@ -0,0 +1,116 @@
package admin
import (
"fmt"
"os"
"text/tabwriter"
"github.com/smallstep/cli/errs"
"github.com/smallstep/cli/flags"
"github.com/smallstep/cli/utils/cautils"
"github.com/urfave/cli"
"go.step.sm/linkedca"
)
func listCommand() cli.Command {
return cli.Command{
Name: "list",
Action: cli.ActionFunc(listAction),
Usage: "list all admins in the CA configuration",
UsageText: `**step beta ca admin list** [**--super**] [**--provisioner**=<string>]
[**--ca-url**=<uri>] [**--root**=<file>]`,
Flags: []cli.Flag{
flags.CaURL,
flags.Root,
cli.BoolFlag{
Name: "super",
Usage: `Only return super-admins.`,
},
cli.StringFlag{
Name: "provisioner",
Usage: `Only return admins linked to this provisioner.`,
},
flags.AdminCert,
flags.AdminKey,
flags.AdminProvisioner,
flags.AdminSubject,
flags.PasswordFile,
},
Description: `**step beta ca admin list** lists all admins in the CA configuration.
## EXAMPLES
List all admins:
'''
$ step beta ca admin list
'''
List only super-admins:
'''
$ step beta ca admin list --super
'''
List only admins without super-admin privileges:
'''
$ step beta ca admin list --super=false
'''
List all admins associated with a given provisioner:
'''
$ step beta ca admin list --provisioner admin-jwk
'''
List only super-admins associated with a given provisioner:
'''
$ step beta ca admin list --super --provisioner admin-jwk
'''
`,
}
}
func listAction(ctx *cli.Context) (err error) {
if err := errs.NumberOfArguments(ctx, 0); err != nil {
return err
}
isSuperAdmin := ctx.IsSet("super") && ctx.Bool("super")
isNotSuperAdmin := ctx.IsSet("super") && !ctx.Bool("super")
client, err := cautils.NewAdminClient(ctx)
if err != nil {
return err
}
admins, err := client.GetAdmins()
if err != nil {
return err
}
cliAdmins, err := listToCLI(ctx, client, admins)
if err != nil {
return err
}
provName := ctx.String("provisioner")
cliAdmins = adminFilter(cliAdmins, func(a *cliAdmin) bool {
if isSuperAdmin && a.Type != linkedca.Admin_SUPER_ADMIN {
return false
}
if isNotSuperAdmin && a.Type == linkedca.Admin_SUPER_ADMIN {
return false
}
if len(provName) > 0 && a.ProvisionerName != provName {
return false
}
return true
})
w := new(tabwriter.Writer)
// Format in tab-separated columns with a tab stop of 8.
w.Init(os.Stdout, 0, 8, 1, '\t', 0)
fmt.Fprintln(w, "SUBJECT\tPROVISIONER\tTYPE")
for _, cliAdm := range cliAdmins {
fmt.Fprintf(w, "%s\t%s (%s)\t%s\n", cliAdm.Subject, cliAdm.ProvisionerName, cliAdm.ProvisionerType, cliAdm.Type)
}
w.Flush()
return nil
}

View File

@@ -0,0 +1,72 @@
package admin
import (
"github.com/smallstep/cli/errs"
"github.com/smallstep/cli/flags"
"github.com/smallstep/cli/utils/cautils"
"github.com/urfave/cli"
)
func removeCommand() cli.Command {
return cli.Command{
Name: "remove",
Action: cli.ActionFunc(removeAction),
Usage: "remove an admin from the CA configuration",
UsageText: `**step beta ca admin remove** <subject> [**--provisioner**=<id>] [**--ca-url**=<uri>]
[**--root**=<file>]`,
Flags: []cli.Flag{
cli.StringFlag{
Name: "provisioner",
Usage: `Filter admins by provisioner name.`,
},
flags.AdminCert,
flags.AdminKey,
flags.AdminProvisioner,
flags.AdminSubject,
flags.PasswordFile,
flags.CaURL,
flags.Root,
},
Description: `**step beta ca admin remove** removes an admin from the CA configuration.
## POSITIONAL ARGUMENTS
<name>
: The name of the admin to be removed.
## EXAMPLES
Remove an admin:
'''
$ step beta ca admin remove max@smallstep.com
'''
Remove an admin with additional filtering by provisioner:
'''
$ step beta ca admin remove max@smallstep.com --provisioner admin-jwk
'''
`,
}
}
func removeAction(ctx *cli.Context) error {
if err := errs.NumberOfArguments(ctx, 1); err != nil {
return err
}
client, err := cautils.NewAdminClient(ctx)
if err != nil {
return err
}
admins, err := client.GetAdmins()
if err != nil {
return err
}
adm, err := adminPrompt(ctx, client, admins)
if err != nil {
return err
}
return client.RemoveAdmin(adm.Id)
}

116
command/ca/admin/update.go Normal file
View File

@@ -0,0 +1,116 @@
package admin
import (
"fmt"
"os"
"text/tabwriter"
adminAPI "github.com/smallstep/certificates/authority/admin/api"
"github.com/smallstep/cli/errs"
"github.com/smallstep/cli/flags"
"github.com/smallstep/cli/utils/cautils"
"github.com/urfave/cli"
"go.step.sm/linkedca"
)
func updateCommand() cli.Command {
return cli.Command{
Name: "update",
Action: cli.ActionFunc(updateAction),
Usage: "update an admin",
UsageText: `**step beta ca admin update** <subject> [**--super**] [**--provisioner**=<name>]
[**--ca-url**=<uri>] [**--root**=<file>]`,
Flags: []cli.Flag{
cli.BoolFlag{
Name: "super",
Usage: `Update the admin with super-admin privileges.`,
},
cli.StringFlag{
Name: "provisioner",
Usage: `Filter admin by provisioner name`,
},
flags.AdminCert,
flags.AdminKey,
flags.AdminProvisioner,
flags.AdminSubject,
flags.PasswordFile,
flags.CaURL,
flags.Root,
},
Description: `**step beta ca admin update** updates an admin.
## POSITIONAL ARGUMENTS
<id>
: The name of the admin to update.
## EXAMPLES
Add super-admin privileges to an admin:
'''
$ step beta ca admin update max@smallstep.com --super
'''
Specify admin by provisioner:
'''
$ step beta ca admin update max@smallstep.com --super --provisioner devops-jwk
'''
Remove super-admin privileges from an admin:
'''
$ step beta ca admin update max@smallstep.com --super=false
'''
`,
}
}
func updateAction(ctx *cli.Context) error {
if err := errs.NumberOfArguments(ctx, 1); err != nil {
return err
}
setSuperAdmin := ctx.IsSet("super") && ctx.Bool("super")
setNotSuperAdmin := ctx.IsSet("super") && !ctx.Bool("super")
if !setSuperAdmin && !setNotSuperAdmin {
return errs.RequiredFlag(ctx, "super")
}
client, err := cautils.NewAdminClient(ctx)
if err != nil {
return err
}
admins, err := client.GetAdmins()
if err != nil {
return err
}
cliAdm, err := adminPrompt(ctx, client, admins)
if err != nil {
return err
}
var typ linkedca.Admin_Type
if setSuperAdmin {
typ = linkedca.Admin_SUPER_ADMIN
}
if setNotSuperAdmin {
typ = linkedca.Admin_ADMIN
}
adm, err := client.UpdateAdmin(cliAdm.Id, &adminAPI.UpdateAdminRequest{
Type: typ,
})
if err != nil {
return err
}
w := new(tabwriter.Writer)
// Format in tab-separated columns with a tab stop of 8.
w.Init(os.Stdout, 0, 8, 1, '\t', 0)
fmt.Fprintln(w, "SUBJECT\tPROVISIONER\tTYPE")
fmt.Fprintf(w, "%s\t%s (%s)\t%s\n", adm.Subject, cliAdm.ProvisionerName, cliAdm.ProvisionerType, adm.Type.String())
w.Flush()
return nil
}

View File

@@ -6,7 +6,9 @@ import (
"github.com/pkg/errors"
"github.com/smallstep/cli/command"
"github.com/smallstep/cli/command/ca/admin"
"github.com/smallstep/cli/command/ca/provisioner"
"github.com/smallstep/cli/command/ca/provisionerbeta"
"github.com/urfave/cli"
)
@@ -192,3 +194,17 @@ func completeURL(rawurl string) (string, error) {
// rawurl looks like ca.smallstep.com:443 or ca.smallstep.com:443/1.0/sign
return completeURL("https://" + rawurl)
}
// BetaCommand enables access to beta APIs.
func BetaCommand() cli.Command {
return cli.Command{
Name: "ca",
Usage: "commads that are made available for testing new features and APIs",
UsageText: "step beta ca <subcommand> [arguments] [global-flags] [subcommand-flags]",
Description: `**step beta ca** enables access to beta APIs..`,
Subcommands: cli.Commands{
admin.Command(),
provisionerbeta.Command(),
},
}
}

View File

@@ -11,7 +11,7 @@ import (
"strings"
"github.com/pkg/errors"
"github.com/smallstep/certificates/authority"
"github.com/smallstep/certificates/authority/config"
"github.com/smallstep/certificates/authority/provisioner"
"github.com/smallstep/cli/crypto/pemutil"
"github.com/smallstep/cli/errs"
@@ -26,7 +26,7 @@ func addCommand() cli.Command {
return cli.Command{
Name: "add",
Action: cli.ActionFunc(addAction),
Usage: "add one or more provisioners the CA configuration",
Usage: "add one or more provisioners to the CA configuration",
UsageText: `**step ca provisioner add** <name> <jwk-file> [<jwk-file> ...]
**--ca-config**=<file> [**--type**=JWK] [**--create**] [**--password-file**=<file>]
@@ -45,7 +45,7 @@ func addCommand() cli.Command {
[**--ca-config**=<file>] [**--aws-account**=<id>]
[**--gcp-service-account**=<name>] [**--gcp-project**=<name>]
[**--azure-tenant**=<id>] [**--azure-resource-group**=<name>]
[**--instance-age**=<duration>] [**--iid-roots**=<path>]
[**--instance-age**=<duration>] [**--iid-roots**=<file>]
[**--disable-custom-sans**] [**--disable-trust-on-first-use**]
**step ca provisioner add** <name> **--type**=ACME **--ca-config**=<file>`,
@@ -315,12 +315,12 @@ func addAction(ctx *cli.Context) (err error) {
args := ctx.Args()
name := args[0]
config := ctx.String("ca-config")
if len(config) == 0 {
caCfg := ctx.String("ca-config")
if len(caCfg) == 0 {
return errs.RequiredFlag(ctx, "ca-config")
}
c, err := authority.LoadConfiguration(config)
c, err := config.LoadConfiguration(caCfg)
if err != nil {
return errors.Wrapf(err, "error loading configuration")
}
@@ -364,7 +364,7 @@ func addAction(ctx *cli.Context) (err error) {
}
c.AuthorityConfig.Provisioners = append(c.AuthorityConfig.Provisioners, list...)
if err = c.Save(config); err != nil {
if err = c.Save(caCfg); err != nil {
return err
}

View File

@@ -15,7 +15,7 @@ func Command() cli.Command {
removeCommand(),
},
Description: `The **step ca provisioner** command group provides facilities for managing the
certificate authority provisioner.
certificate authority provisioners.
A provisioner is an entity that controls provisioning credentials, which are
used to generate provisioning tokens.

View File

@@ -4,7 +4,7 @@ import (
"strings"
"github.com/pkg/errors"
"github.com/smallstep/certificates/authority"
"github.com/smallstep/certificates/authority/config"
"github.com/smallstep/certificates/authority/provisioner"
"github.com/smallstep/cli/errs"
"github.com/smallstep/cli/ui"
@@ -122,13 +122,13 @@ func removeAction(ctx *cli.Context) error {
}
name := ctx.Args().Get(0)
config := ctx.String("ca-config")
caCfg := ctx.String("ca-config")
all := ctx.Bool("all")
kid := ctx.String("kid")
clientID := ctx.String("client-id")
typ := ctx.String("type")
if len(config) == 0 {
if len(caCfg) == 0 {
return errs.RequiredFlag(ctx, "ca-config")
}
@@ -149,7 +149,7 @@ func removeAction(ctx *cli.Context) error {
}
}
c, err := authority.LoadConfiguration(config)
c, err := config.LoadConfiguration(caCfg)
if err != nil {
return errors.Wrapf(err, "error loading configuration")
}
@@ -197,7 +197,7 @@ func removeAction(ctx *cli.Context) error {
}
c.AuthorityConfig.Provisioners = provisioners
if err = c.Save(config); err != nil {
if err = c.Save(caCfg); err != nil {
return err
}

View File

@@ -0,0 +1,702 @@
package provisionerbeta
import (
"bytes"
"crypto/ecdsa"
"crypto/ed25519"
"crypto/rsa"
"crypto/x509"
"encoding/json"
"encoding/pem"
"fmt"
"io/ioutil"
"net/url"
"github.com/pkg/errors"
"github.com/smallstep/certificates/authority/provisioner"
"github.com/smallstep/cli/crypto/pemutil"
"github.com/smallstep/cli/errs"
"github.com/smallstep/cli/flags"
"github.com/smallstep/cli/jose"
"github.com/smallstep/cli/ui"
"github.com/smallstep/cli/utils"
"github.com/smallstep/cli/utils/cautils"
"github.com/urfave/cli"
"go.step.sm/linkedca"
"google.golang.org/protobuf/encoding/protojson"
)
func addCommand() cli.Command {
return cli.Command{
Name: "add",
Action: cli.ActionFunc(addAction),
Usage: "add a provisioner",
UsageText: `**step beta ca provisioner add** <name> **--type**=JWK [**--public-key**=<file>]
[**--private-key**=<file>] [**--create**] [**--password-file**=<file>]
[**--ca-url**=<uri>] [**--root**=<file>]
**step beta ca provisioner add** <name> **--type**=OIDC
[**--client-id**=<id>] [**--client-secret**=<secret>]
[**--configuration-endpoint**=<url>] [**--domain**=<domain>]
[**--admin**=<email>]... [**--ca-url**=<uri>] [**--root**=<file>]
**step beta ca provisioner add** <name> **--type**=X5C **--x5c-root**=<file>
[**--ca-url**=<uri>] [**--root**=<file>]
**step beta ca provisioner add** <name> **--type**=SSHPOP
[**--ca-url**=<uri>] [**--root**=<file>]
**step beta ca provisioner add** <name> **--type**=K8SSA [**--public-key**=<file>]
[**--ca-url**=<uri>] [**--root**=<file>]
**step beta ca provisioner add** <name> **--type**=[AWS|Azure|GCP]
[**--aws-account**=<id>] [**--gcp-service-account**=<name>] [**--gcp-project**=<name>]
[**--azure-tenant**=<id>] [**--azure-resource-group**=<name>]
[**--instance-age**=<duration>] [**--iid-roots**=<file>]
[**--disable-custom-sans**] [**--disable-trust-on-first-use**]
[**--ca-url**=<uri>] [**--root**=<file>]
**step beta ca provisioner add** <name> **--type**=ACME [**--force-cn**]
[**--ca-url**=<uri>] [**--root**=<file>]`,
Flags: []cli.Flag{
cli.StringFlag{
Name: "type",
Value: provisioner.TypeJWK.String(),
Usage: `The <type> of provisioner to create.
: <type> is a case-insensitive string and must be one of:
**JWK**
: Uses an JWK key pair to sign provisioning tokens. (default)
**OIDC**
: Uses an OpenID Connect provider to sign provisioning tokens.
**AWS**
: Uses Amazon AWS instance identity documents.
**GCP**
: Use Google instance identity tokens.
**Azure**
: Uses Microsoft Azure identity tokens.
**ACME**
: Uses the ACME protocol to create certificates.
**X5C**
: Uses an X509 Certificate / private key pair to sign provisioning tokens.
**K8SSA**
: Uses Kubernetes Service Account tokens.
**SSHPOP**
: Uses an SSH Certificate / private key pair to sign provisioning tokens.`},
x509TemplateFlag,
x509TemplateDataFlag,
sshTemplateFlag,
sshTemplateDataFlag,
x509MinDurFlag,
x509MaxDurFlag,
x509DefaultDurFlag,
sshUserMinDurFlag,
sshUserMaxDurFlag,
sshUserDefaultDurFlag,
sshHostMinDurFlag,
sshHostMaxDurFlag,
sshHostDefaultDurFlag,
disableRenewalFlag,
enableX509Flag,
enableSSHFlag,
// JWK provisioner flags
cli.BoolFlag{
Name: "create",
Usage: `Create the JWK key pair for the provisioner.`,
},
cli.StringFlag{
Name: "private-key",
Usage: `The <file> containing the JWK private key.`,
},
cli.StringFlag{
Name: "public-key",
Usage: `The <file> containing the JWK public key.`,
},
// OIDC provisioner flags
cli.StringFlag{
Name: "client-id",
Usage: `The <id> used to validate the audience in an OpenID Connect token.`,
},
cli.StringFlag{
Name: "client-secret",
Usage: `The <secret> used to obtain the OpenID Connect tokens.`,
},
cli.StringFlag{
Name: "listen-address",
Usage: `The callback <address> used in the OpenID Connect flow (e.g. \":10000\")`,
},
cli.StringFlag{
Name: "configuration-endpoint",
Usage: `OpenID Connect configuration <url>.`,
},
cli.StringSliceFlag{
Name: "admin",
Usage: `The <email> of an admin user in an OpenID Connect provisioner, this user
will not have restrictions in the certificates to sign. Use the
'--admin' flag multiple times to configure multiple administrators.`,
},
cli.StringSliceFlag{
Name: "group",
Usage: `The <group> list used to validate the groups extenstion in an OpenID Connect token.
Use the '--group' flag multiple times to configure multiple groups.`,
},
cli.StringFlag{
Name: "tenant-id",
Usage: `The <tenant-id> used to replace the templatized {tenantid} in the OpenID Configuration.`,
},
// X5C provisioner flags
cli.StringFlag{
Name: "x5c-root",
Usage: `Root certificate (chain) <file> used to validate the signature on X5C
provisioning tokens.`,
},
// ACME provisioner flags
forceCNFlag,
// Cloud provisioner flags
awsAccountFlag,
azureTenantFlag,
azureResourceGroupFlag,
gcpServiceAccountFlag,
gcpProjectFlag,
instanceAgeFlag,
iidRootsFlag,
disableCustomSANsFlag,
disableTOFUFlag,
flags.AdminCert,
flags.AdminKey,
flags.AdminProvisioner,
flags.AdminSubject,
flags.PasswordFile,
flags.CaURL,
flags.Root,
},
Description: `**step ca provisioner add** adds a provisioner to the CA configuration.
## POSITIONAL ARGUMENTS
<name>
: The name of the provisioner.
## EXAMPLES
Create a JWK provisioner with newly generated keys and a template for x509 certificates:
'''
step beta ca provisioner add cicd --type JWK --create --x509-template ./templates/example.tpl
'''
Create a JWK provisioner with duration claims:
'''
step beta ca provisioner add cicd --type JWK --create --x509-min-dur 20m --x509-default-dur 48h --ssh-user-min-dur 17m --ssh-host-default-dur 16h
'''
Create a JWK provisioner with existing keys:
'''
step beta ca provisioner add jane@doe.com --type JWK --public-key jwk.pub --private-key jwk.priv
'''
Create an OIDC provisioner:
'''
step beta ca provisioner add Google --type OIDC --ssh \
--client-id 1087160488420-8qt7bavg3qesdhs6it824mhnfgcfe8il.apps.googleusercontent.com \
--client-secret udTrOT3gzrO7W9fDPgZQLfYJ \
--configuration-endpoint https://accounts.google.com/.well-known/openid-configuration
'''
Create an X5C provisioner:
'''
step beta ca provisioner add x5c --type X5C --x5c-root x5c_ca.crt
'''
Create an ACME provisioner:
'''
step beta ca provisioner add acme --type ACME
'''
Create an K8SSA provisioner:
'''
step beta ca provisioner add kube --type K8SSA --ssh --public-key key.pub
'''
Create an SSHPOP provisioner for renewing SSH host certificates:")
'''
step beta ca provisioner add sshpop --type SSHPOP
'''
Create an Azure provisioner with two service groups:
'''
$ step beta ca provisioner add Azure --type Azure \
--azure-tenant bc9043e2-b645-4c1c-a87a-78f8644bfe57 \
--azure-resource-group identity --azure-resource-group accounting
'''
Create an GCP provisioner that will only accept the SANs provided in the identity token:
'''
$ step beta ca provisioner add Google --type GCP \
--disable-custom-sans --gcp-project internal
'''
Create an AWS provisioner that will only accept the SANs provided in the identity
document and will allow multiple certificates from the same instance:
'''
$ step beta ca provisioner add Amazon --type AWS \
--aws-account 123456789 --disable-custom-sans --disable-trust-on-first-use
'''
Create an AWS provisioner that will use a custom certificate to validate the instance
identity documents:
'''
$ step beta ca provisioner add Amazon --type AWS \
--aws-account 123456789 --iid-roots $(step path)/certs/aws.crt
'''`,
}
}
func addAction(ctx *cli.Context) (err error) {
if err := errs.NumberOfArguments(ctx, 1); err != nil {
return err
}
x509TemplateFile := ctx.String("x509-template")
x509TemplateDataFile := ctx.String("x509-template-data")
sshTemplateFile := ctx.String("ssh-template")
sshTemplateDataFile := ctx.String("ssh-template-data")
args := ctx.Args()
typ := ctx.String("type")
p := &linkedca.Provisioner{
Name: args.Get(0),
}
// Read x509 template if passed
p.X509Template = &linkedca.Template{}
if x509TemplateFile != "" {
b, err := utils.ReadFile(x509TemplateFile)
if err != nil {
return err
}
p.X509Template.Template = b
}
if x509TemplateDataFile != "" {
b, err := utils.ReadFile(x509TemplateDataFile)
if err != nil {
return err
}
p.X509Template.Data = b
}
// Read ssh template if passed
p.SshTemplate = &linkedca.Template{}
if sshTemplateFile != "" {
b, err := utils.ReadFile(sshTemplateFile)
if err != nil {
return err
}
p.SshTemplate.Template = b
}
if sshTemplateDataFile != "" {
b, err := utils.ReadFile(sshTemplateDataFile)
if err != nil {
return err
}
p.SshTemplate.Data = b
}
p.Claims = &linkedca.Claims{
X509: &linkedca.X509Claims{
Durations: &linkedca.Durations{
Min: ctx.String("x509-min-dur"),
Max: ctx.String("x509-max-dur"),
Default: ctx.String("x509-default-dur"),
},
Enabled: !(ctx.IsSet("x509") && !ctx.Bool("x509")),
},
Ssh: &linkedca.SSHClaims{
UserDurations: &linkedca.Durations{
Min: ctx.String("ssh-user-min-dur"),
Max: ctx.String("ssh-user-max-dur"),
Default: ctx.String("ssh-user-default-dur"),
},
HostDurations: &linkedca.Durations{
Min: ctx.String("ssh-host-min-dur"),
Max: ctx.String("ssh-host-max-dur"),
Default: ctx.String("ssh-host-default-dur"),
},
Enabled: !(ctx.IsSet("ssh") && !ctx.Bool("ssh")),
},
DisableRenewal: ctx.Bool("disable-renewal"),
}
client, err := cautils.NewAdminClient(ctx)
if err != nil {
return err
}
switch typ {
case linkedca.Provisioner_JWK.String():
p.Type = linkedca.Provisioner_JWK
p.Details, err = createJWKDetails(ctx)
case linkedca.Provisioner_ACME.String():
p.Type = linkedca.Provisioner_ACME
p.Details, err = createACMEDetails(ctx)
case linkedca.Provisioner_SSHPOP.String():
p.Type = linkedca.Provisioner_SSHPOP
p.Details, err = createSSHPOPDetails(ctx)
case linkedca.Provisioner_X5C.String():
p.Type = linkedca.Provisioner_X5C
p.Details, err = createX5CDetails(ctx)
case linkedca.Provisioner_K8SSA.String():
p.Type = linkedca.Provisioner_K8SSA
p.Details, err = createK8SSADetails(ctx)
case linkedca.Provisioner_OIDC.String():
p.Type = linkedca.Provisioner_OIDC
p.Details, err = createOIDCDetails(ctx)
case linkedca.Provisioner_AWS.String():
p.Type = linkedca.Provisioner_AWS
p.Details, err = createAWSDetails(ctx)
case linkedca.Provisioner_AZURE.String():
p.Type = linkedca.Provisioner_AZURE
p.Details, err = createAzureDetails(ctx)
case linkedca.Provisioner_GCP.String():
p.Type = linkedca.Provisioner_GCP
p.Details, err = createGCPDetails(ctx)
// TODO add SCEP provisioner support.
default:
return fmt.Errorf("unsupported provisioner type %s", typ)
}
if err != nil {
return err
}
if p, err = client.CreateProvisioner(p); err != nil {
return err
}
var buf bytes.Buffer
b, err := protojson.Marshal(p)
if err != nil {
return err
}
if err := json.Indent(&buf, b, "", " "); err != nil {
return err
}
fmt.Println(buf.String())
return nil
}
func createJWKDetails(ctx *cli.Context) (*linkedca.ProvisionerDetails, error) {
var (
err error
password string
)
if passwordFile := ctx.String("password-file"); len(passwordFile) > 0 {
password, err = utils.ReadStringPasswordFromFile(passwordFile)
if err != nil {
return nil, err
}
}
var (
jwk *jose.JSONWebKey
jwe *jose.JSONWebEncryption
)
if ctx.Bool("create") {
if ctx.IsSet("public-key") {
return nil, errs.IncompatibleFlag(ctx, "create", "public-key")
}
if ctx.IsSet("private-key") {
return nil, errs.IncompatibleFlag(ctx, "create", "private-key")
}
pass, err := ui.PromptPasswordGenerate("Please enter a password to encrypt the provisioner private key? [leave empty and we'll generate one]", ui.WithValue(password))
if err != nil {
return nil, err
}
jwk, jwe, err = jose.GenerateDefaultKeyPair(pass)
if err != nil {
return nil, err
}
} else {
if !ctx.IsSet("public-key") {
return nil, errs.RequiredWithFlagValue(ctx, "create", "false", "public-key")
}
jwkFile := ctx.String("public-key")
jwk, err = jose.ParseKey(jwkFile)
if err != nil {
return nil, errs.FileError(err, jwkFile)
}
// Only use asymmetric cryptography
if _, ok := jwk.Key.([]byte); ok {
return nil, errors.New("invalid JWK: a symmetric key cannot be used as a provisioner")
}
// Create kid if not present
if len(jwk.KeyID) == 0 {
jwk.KeyID, err = jose.Thumbprint(jwk)
if err != nil {
return nil, err
}
}
if ctx.IsSet("private-key") {
jwkFile = ctx.String("private-key")
b, err := ioutil.ReadFile(jwkFile)
if err != nil {
return nil, errors.Wrapf(err, "error reading %s", jwkFile)
}
// Attempt to parse private key as Encrypted JSON.
// If this operation fails then either,
// 1. the key is not encrypted
// 2. the key has an invalid format
//
// Attempt to parse as decrypted private key.
jwe, err = jose.ParseEncrypted(string(b))
if err != nil {
privjwk, err := jose.ParseKey(jwkFile)
if err != nil {
return nil, errs.FileError(err, jwkFile)
}
if privjwk.IsPublic() {
return nil, errors.New("invalid jwk: private-key is a public key")
}
// Encrypt JWK
opts := []jose.Option{}
if ctx.IsSet("password-file") {
opts = append(opts, jose.WithPasswordFile(ctx.String("password-file")))
}
jwe, err = jose.EncryptJWK(privjwk, opts...)
if err != nil {
return nil, err
}
}
}
}
jwkPubBytes, err := jwk.MarshalJSON()
if err != nil {
return nil, errors.Wrap(err, "error marshaling JWK")
}
jwkProv := &linkedca.JWKProvisioner{
PublicKey: jwkPubBytes,
}
if jwe != nil {
jwePrivStr, err := jwe.CompactSerialize()
if err != nil {
return nil, errors.Wrap(err, "error serializing JWE")
}
jwkProv.EncryptedPrivateKey = []byte(jwePrivStr)
}
return &linkedca.ProvisionerDetails{
Data: &linkedca.ProvisionerDetails_JWK{
JWK: jwkProv,
},
}, nil
}
func createACMEDetails(ctx *cli.Context) (*linkedca.ProvisionerDetails, error) {
return &linkedca.ProvisionerDetails{
Data: &linkedca.ProvisionerDetails_ACME{
ACME: &linkedca.ACMEProvisioner{
ForceCn: ctx.Bool("force-cn"),
},
},
}, nil
}
func createSSHPOPDetails(ctx *cli.Context) (*linkedca.ProvisionerDetails, error) {
return &linkedca.ProvisionerDetails{
Data: &linkedca.ProvisionerDetails_SSHPOP{
SSHPOP: &linkedca.SSHPOPProvisioner{},
},
}, nil
}
func createX5CDetails(ctx *cli.Context) (*linkedca.ProvisionerDetails, error) {
x5cRootFile := ctx.String("x5c-root")
if len(x5cRootFile) == 0 {
return nil, errs.RequiredWithFlagValue(ctx, "type", "x5c", "x5c-root")
}
roots, err := pemutil.ReadCertificateBundle(x5cRootFile)
if err != nil {
return nil, errors.Wrapf(err, "error loading X5C Root certificates from %s", x5cRootFile)
}
var rootBytes [][]byte
for _, r := range roots {
if r.KeyUsage&x509.KeyUsageCertSign == 0 {
return nil, errors.Errorf("error: certificate with common name '%s' cannot be "+
"used as an X5C root certificate.\n\n"+
"X5C provisioner root certificates must have the 'Certificate Sign' key "+
"usage extension.", r.Subject.CommonName)
}
rootBytes = append(rootBytes, pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE",
Bytes: r.Raw,
}))
}
return &linkedca.ProvisionerDetails{
Data: &linkedca.ProvisionerDetails_X5C{
X5C: &linkedca.X5CProvisioner{
Roots: rootBytes,
},
},
}, nil
}
func createK8SSADetails(ctx *cli.Context) (*linkedca.ProvisionerDetails, error) {
pemKeysF := ctx.String("public-key")
if len(pemKeysF) == 0 {
return nil, errs.RequiredWithFlagValue(ctx, "type", "k8sSA", "public-key")
}
pemKeysB, err := ioutil.ReadFile(pemKeysF)
if err != nil {
return nil, errors.Wrap(err, "error reading pem keys")
}
var (
block *pem.Block
rest = pemKeysB
pemKeys = []interface{}{}
)
for rest != nil {
block, rest = pem.Decode(rest)
if block == nil {
break
}
key, err := pemutil.ParseKey(pem.EncodeToMemory(block))
if err != nil {
return nil, errors.Wrapf(err, "error parsing public key from %s", pemKeysF)
}
switch q := key.(type) {
case *rsa.PublicKey, *ecdsa.PublicKey, ed25519.PublicKey:
default:
return nil, errors.Errorf("Unexpected public key type %T in %s", q, pemKeysF)
}
pemKeys = append(pemKeys, key)
}
var pubKeyBytes [][]byte
for _, k := range pemKeys {
blk, err := pemutil.Serialize(k)
if err != nil {
return nil, errors.Wrap(err, "error serializing pem key")
}
pubKeyBytes = append(pubKeyBytes, pem.EncodeToMemory(blk))
}
return &linkedca.ProvisionerDetails{
Data: &linkedca.ProvisionerDetails_K8SSA{
K8SSA: &linkedca.K8SSAProvisioner{
PublicKeys: pubKeyBytes,
},
},
}, nil
}
func createOIDCDetails(ctx *cli.Context) (*linkedca.ProvisionerDetails, error) {
clientID := ctx.String("client-id")
if len(clientID) == 0 {
return nil, errs.RequiredWithFlagValue(ctx, "type", ctx.String("type"), "client-id")
}
confURL := ctx.String("configuration-endpoint")
if len(confURL) == 0 {
return nil, errs.RequiredWithFlagValue(ctx, "type", ctx.String("type"), "configuration-endpoint")
}
u, err := url.Parse(confURL)
if err != nil || (u.Scheme != "https" && u.Scheme != "http") {
return nil, errs.InvalidFlagValue(ctx, "configuration-endpoint", confURL, "")
}
return &linkedca.ProvisionerDetails{
Data: &linkedca.ProvisionerDetails_OIDC{
OIDC: &linkedca.OIDCProvisioner{
ClientId: clientID,
ClientSecret: ctx.String("client-secret"),
ConfigurationEndpoint: confURL,
Admins: ctx.StringSlice("admin"),
Domains: ctx.StringSlice("domain"),
Groups: ctx.StringSlice("group"),
ListenAddress: ctx.String("listen-address"),
TenantId: ctx.String("tenant-id"),
},
},
}, nil
}
func createAWSDetails(ctx *cli.Context) (*linkedca.ProvisionerDetails, error) {
d, err := parseIntaceAge(ctx)
if err != nil {
return nil, err
}
return &linkedca.ProvisionerDetails{
Data: &linkedca.ProvisionerDetails_AWS{
AWS: &linkedca.AWSProvisioner{
Accounts: ctx.StringSlice("aws-account"),
DisableCustomSans: ctx.Bool("disable-custom-sans"),
DisableTrustOnFirstUse: ctx.Bool("disable-trust-on-first-use"),
InstanceAge: d,
// TODO IID Roots
// IIDRoots: ctx.String("iid-roots"),
},
},
}, nil
}
func createAzureDetails(ctx *cli.Context) (*linkedca.ProvisionerDetails, error) {
tenantID := ctx.String("azure-tenant")
if tenantID == "" {
return nil, errs.RequiredWithFlagValue(ctx, "type", ctx.String("type"), "azure-tenant")
}
return &linkedca.ProvisionerDetails{
Data: &linkedca.ProvisionerDetails_Azure{
Azure: &linkedca.AzureProvisioner{
TenantId: tenantID,
ResourceGroups: ctx.StringSlice("azure-resource-group"),
DisableCustomSans: ctx.Bool("disable-custom-sans"),
DisableTrustOnFirstUse: ctx.Bool("disable-trust-on-first-use"),
},
},
}, nil
}
func createGCPDetails(ctx *cli.Context) (*linkedca.ProvisionerDetails, error) {
d, err := parseIntaceAge(ctx)
if err != nil {
return nil, err
}
return &linkedca.ProvisionerDetails{
Data: &linkedca.ProvisionerDetails_GCP{
GCP: &linkedca.GCPProvisioner{
ServiceAccounts: ctx.StringSlice("gcp-service-account"),
ProjectIds: ctx.StringSlice("gcp-project"),
DisableCustomSans: ctx.Bool("disable-custom-sans"),
DisableTrustOnFirstUse: ctx.Bool("disable-trust-on-first-use"),
InstanceAge: d,
},
},
}, nil
}

View File

@@ -0,0 +1,72 @@
package provisionerbeta
import (
"bytes"
"encoding/json"
"fmt"
"github.com/smallstep/certificates/ca"
"github.com/smallstep/cli/errs"
"github.com/smallstep/cli/flags"
"github.com/smallstep/cli/utils/cautils"
"github.com/urfave/cli"
"google.golang.org/protobuf/encoding/protojson"
)
func getCommand() cli.Command {
return cli.Command{
Name: "get",
Action: cli.ActionFunc(getAction),
Usage: "get a provisioner from the CA configuration",
UsageText: `**step beta ca provisioner get** <name> [**--ca-url**=<uri>] [**--root**=<file>]`,
Flags: []cli.Flag{
flags.AdminCert,
flags.AdminKey,
flags.AdminProvisioner,
flags.AdminSubject,
flags.CaURL,
flags.Root,
},
Description: `**step beta ca provisioner get** gets a provisioner from the CA configuration.
## EXAMPLES
Get a provisioner by name:
'''
$ step beta ca provisioner get acme
'''
`,
}
}
func getAction(ctx *cli.Context) (err error) {
if err := errs.NumberOfArguments(ctx, 1); err != nil {
return err
}
args := ctx.Args()
name := args.Get(0)
// Create online client
client, err := cautils.NewAdminClient(ctx)
if err != nil {
return err
}
p, err := client.GetProvisioner(ca.WithProvisionerName(name))
if err != nil {
return err
}
var buf bytes.Buffer
b, err := protojson.Marshal(p)
if err != nil {
return err
}
if err := json.Indent(&buf, b, "", " "); err != nil {
return err
}
fmt.Println(buf.String())
return nil
}

View File

@@ -0,0 +1,241 @@
package provisionerbeta
import (
"time"
"github.com/smallstep/cli/errs"
"github.com/urfave/cli"
)
// Command returns the jwk subcommand.
func Command() cli.Command {
return cli.Command{
Name: "provisioner",
Usage: "create and manage the certificate authority provisioners",
UsageText: "step beta ca provisioner <subcommand> [arguments] [global-flags] [subcommand-flags]",
Subcommands: cli.Commands{
//listCommand(),
addCommand(),
removeCommand(),
getCommand(),
updateCommand(),
},
Description: `The **step beta ca provisioner** command group provides facilities for managing the
certificate authority provisioners.
A provisioner is an entity that controls provisioning credentials, which are
used to generate provisioning tokens.
Provisioning credentials are simple JWK key pairs using public-key cryptography.
The public key is used to verify a provisioning token while the private key is
used to sign the provisioning token.
Provisioning tokens are JWT tokens signed by the JWK private key. These JWT
tokens are used to get a valid TLS certificate from the certificate authority.
Each provisioner is able to manage a different set of rules that can be used to
configure the bounds of the certificate.
In the certificate authority, a provisioner is configured with a JSON object
with the following properties:
* **name**: the provisioner name, it will become the JWT issuer and a good
practice is to use an email address for this.
* **type**: the provisioner type, currently only "jwk" is supported.
* **key**: the JWK public key used to verify the provisioning tokens.
* **encryptedKey** (optional): the JWE compact serialization of the private key
used to sign the provisioning tokens.
* **claims** (optional): an object with custom options for each provisioner.
Options supported are:
* **minTLSCertDuration**: minimum duration of a certificate, set to 5m by
default.
* **maxTLSCertDuration**: maximum duration of a certificate, set to 24h by
default.
* **defaultTLSCertDuration**: default duration of the certificate, set to 24h
by default.
* **disableRenewal**: whether or not to disable certificate renewal, set to false
by default.
## EXAMPLES
Add a single provisioner:
'''
$ step beta ca provisioner add max@smallstep.com --type JWK --create
'''
Remove a provisioner:
'''
$ step beta ca provisioner remove max@smallstep.com
'''`,
}
}
func parseIntaceAge(ctx *cli.Context) (age string, err error) {
if !ctx.IsSet("instance-age") {
return
}
age = ctx.String("instance-age")
dur, err := time.ParseDuration(age)
if err != nil {
return "", err
}
if dur < 0 {
return "", errs.MinSizeFlag(ctx, "instance-age", "0s")
}
return
}
func removeElements(list []string, rems []string) []string {
if len(list) == 0 {
return list
}
for _, rem := range rems {
for i, elem := range list {
if elem == rem {
list[i] = list[len(list)-1]
list = list[:len(list)-1]
break
}
}
}
return list
}
var (
x509TemplateFlag = cli.StringFlag{
Name: "x509-template",
Usage: `The x509 certificate template <file>, a JSON representation of the certificate to create.`,
}
x509TemplateDataFlag = cli.StringFlag{
Name: "x509-template-data",
Usage: `The x509 certificate template data <file>, a JSON map of data that can be used by the certificate template.`,
}
sshTemplateFlag = cli.StringFlag{
Name: "ssh-template",
Usage: `The x509 certificate template <file>, a JSON representation of the certificate to create.`,
}
sshTemplateDataFlag = cli.StringFlag{
Name: "ssh-template-data",
Usage: `The ssh certificate template data <file>, a JSON map of data that can be used by the certificate template.`,
}
x509MinDurFlag = cli.StringFlag{
Name: "x509-min-dur",
Usage: `The minimum <duration> for an x509 certificate generated by this provisioner.`,
}
x509MaxDurFlag = cli.StringFlag{
Name: "x509-max-dur",
Usage: `The maximum <duration> for an x509 certificate generated by this provisioner.`,
}
x509DefaultDurFlag = cli.StringFlag{
Name: "x509-default-dur",
Usage: `The default <duration> for an x509 certificate generated by this provisioner.`,
}
sshUserMinDurFlag = cli.StringFlag{
Name: "ssh-user-min-dur",
Usage: `The minimum <duration> for an ssh user certificate generated by this provisioner.`,
}
sshUserMaxDurFlag = cli.StringFlag{
Name: "ssh-user-max-dur",
Usage: `The maximum <duration> for an ssh user certificate generated by this provisioner.`,
}
sshUserDefaultDurFlag = cli.StringFlag{
Name: "ssh-user-default-dur",
Usage: `The maximum <duration> for an ssh user certificate generated by this provisioner.`,
}
sshHostMinDurFlag = cli.StringFlag{
Name: "ssh-host-min-dur",
Usage: `The minimum <duration> for an ssh host certificate generated by this provisioner.`,
}
sshHostMaxDurFlag = cli.StringFlag{
Name: "ssh-host-max-dur",
Usage: `The maximum <duration> for an ssh host certificate generated by this provisioner.`,
}
sshHostDefaultDurFlag = cli.StringFlag{
Name: "ssh-host-default-dur",
Usage: `The maximum <duration> for an ssh host certificate generated by this provisioner.`,
}
disableRenewalFlag = cli.BoolFlag{
Name: "disable-renewal",
Usage: `Disable renewal for all certificates generated by this provisioner`,
}
enableX509Flag = cli.BoolFlag{
Name: "x509",
Usage: `Enable provisioning of x509 certificates.`,
}
enableSSHFlag = cli.BoolFlag{
Name: "ssh",
Usage: `Enable provisioning of ssh certificates.`,
}
forceCNFlag = cli.BoolFlag{
Name: "force-cn",
Usage: `Always set the common name in provisioned certificates.`,
}
// Cloud provisioner flags
awsAccountFlag = cli.StringSliceFlag{
Name: "aws-account",
Usage: `The AWS account <id> used to validate the identity documents.
Use the flag multiple times to configure multiple accounts.`,
}
removeAWSAccountFlag = cli.StringSliceFlag{
Name: "remove-aws-account",
Usage: `Remove an AWS account <id> used to validate the identity documents.
Use the flag multiple times to remove multiple accounts.`,
}
azureTenantFlag = cli.StringFlag{
Name: "azure-tenant",
Usage: `The Microsoft Azure tenant <id> used to validate the identity tokens.`,
}
azureResourceGroupFlag = cli.StringSliceFlag{
Name: "azure-resource-group",
Usage: `The Microsoft Azure resource group <name> used to validate the identity tokens.
Use the flag multipl etimes to configure multiple resource groups`,
}
removeAzureResourceGroupFlag = cli.StringSliceFlag{
Name: "remove-azure-resource-group",
Usage: `Remove a Microsoft Azure resource group <name> used to validate the identity tokens.
Use the flag multipl etimes to configure multiple resource groups`,
}
gcpServiceAccountFlag = cli.StringSliceFlag{
Name: "gcp-service-account",
Usage: `The Google service account <email> or <id> used to validate the identity tokens.
Use the flag multiple times to configure multiple service accounts.`,
}
removeGCPServiceAccountFlag = cli.StringSliceFlag{
Name: "remove-gcp-service-account",
Usage: `Remove a Google service account <email> or <id> used to validate the identity tokens.
Use the flag multiple times to configure multiple service accounts.`,
}
gcpProjectFlag = cli.StringSliceFlag{
Name: "gcp-project",
Usage: `The Google project <id> used to validate the identity tokens.
Use the flag multipl etimes to configure multiple projects`,
}
removeGCPProjectFlag = cli.StringSliceFlag{
Name: "remove-gcp-project",
Usage: `Remove a Google project <id> used to validate the identity tokens.
Use the flag multipl etimes to configure multiple projects`,
}
instanceAgeFlag = cli.DurationFlag{
Name: "instance-age",
Usage: `The maximum <duration> to grant a certificate in AWS and GCP provisioners.
A <duration> is sequence of decimal numbers, each with optional fraction and a
unit suffix, such as "300ms", "-1.5h" or "2h45m". Valid time units are "ns",
"us" (or "µs"), "ms", "s", "m", "h".`,
}
iidRootsFlag = cli.StringFlag{
Name: "iid-roots",
Usage: `The <path> to the file containing the certificates used to validate the
instance identity documents in AWS.`,
}
disableCustomSANsFlag = cli.BoolFlag{
Name: "disable-custom-sans",
Usage: `On cloud provisioners, if anabled only the internal DNS and IP will be added as a SAN.
By default it will accept any SAN in the CSR.`,
}
disableTOFUFlag = cli.BoolFlag{
Name: "disable-trust-on-first-use,disable-tofu",
Usage: `On cloud provisioners, if enabled multiple sign request for this provisioner
with the same instance will be accepted. By default only the first request
will be accepted.`,
}
)

View File

@@ -0,0 +1,52 @@
package provisionerbeta
import (
"github.com/smallstep/certificates/ca"
"github.com/smallstep/cli/errs"
"github.com/smallstep/cli/flags"
"github.com/smallstep/cli/utils/cautils"
"github.com/urfave/cli"
)
func removeCommand() cli.Command {
return cli.Command{
Name: "remove",
Action: cli.ActionFunc(removeAction),
Usage: "remove a provisioner from the CA configuration",
UsageText: `**step beta ca provisioner remove** <name> [**--ca-url**=<uri>] [**--root**=<file>]`,
Flags: []cli.Flag{
flags.AdminCert,
flags.AdminKey,
flags.AdminProvisioner,
flags.AdminSubject,
flags.PasswordFile,
flags.CaURL,
flags.Root,
},
Description: `**step beta ca provisioner remove** removes a provisioner from the CA configuration.
## EXAMPLES
Remove provisioner by name:
'''
$ step beta ca provisioner remove acme
'''
`,
}
}
func removeAction(ctx *cli.Context) (err error) {
if err := errs.NumberOfArguments(ctx, 1); err != nil {
return err
}
args := ctx.Args()
name := args.Get(0)
client, err := cautils.NewAdminClient(ctx)
if err != nil {
return err
}
return client.RemoveProvisioner(ca.WithProvisionerName(name))
}

View File

@@ -0,0 +1,764 @@
package provisionerbeta
import (
"bytes"
"crypto/ecdsa"
"crypto/ed25519"
"crypto/rsa"
"crypto/x509"
"encoding/json"
"encoding/pem"
"fmt"
"io/ioutil"
"net/url"
"github.com/pkg/errors"
"github.com/smallstep/certificates/ca"
"github.com/smallstep/cli/crypto/pemutil"
"github.com/smallstep/cli/errs"
"github.com/smallstep/cli/flags"
"github.com/smallstep/cli/jose"
"github.com/smallstep/cli/ui"
"github.com/smallstep/cli/utils"
"github.com/smallstep/cli/utils/cautils"
"github.com/urfave/cli"
"go.step.sm/linkedca"
"google.golang.org/protobuf/encoding/protojson"
)
func updateCommand() cli.Command {
return cli.Command{
Name: "update",
Action: cli.ActionFunc(updateAction),
Usage: "update a provisioner",
UsageText: `**step beta ca provisioner update** <name> [**--public-key**=<file>]
[**--private-key**=<file>] [**--create**] [**--password-file**=<file>]
[**--ca-url**=<uri>] [**--root**=<file>]
**step beta ca provisioner update** <name> [**--force-cn**]
[**--ca-url**=<uri>] [**--root**=<file>]
**step beta ca provisioner update** <name>
[**--client-id**=<id>] [**--client-secret**=<secret>]
[**--configuration-endpoint**=<url>] [**--domain**=<domain>]
[**--admin**=<email>]... [**--remove-admin**=<email>]...
[**--ca-url**=<uri>] [**--root**=<file>]
**step beta ca provisioner update** <name> **--x5c-root**=<file>
[**--ca-url**=<uri>] [**--root**=<file>]
**step beta ca provisioner update** <name> [**--public-key**=<file>]
[**--ca-url**=<uri>] [**--root**=<file>]
**step beta ca provisioner update** <name>
[**--aws-account**=<id>]... [**--remove-aws-account**=<id>]...
[**--gcp-service-account**=<name>]... [**--remove-gcp-service-account**=<name>]...
[**--gcp-project**=<name>]... [**--remove-gcp-project**=<name]...
[**--azure-tenant**=<id>] [**--azure-resource-group**=<name>]
[**--instance-age**=<duration>] [**--iid-roots**=<file>]
[**--disable-custom-sans**] [**--disable-trust-on-first-use**]
[**--ca-url**=<uri>] [**--root**=<file>]`,
Flags: []cli.Flag{
cli.StringFlag{
Name: "name",
Usage: `The new <name> for the provisioner.`,
},
x509TemplateFlag,
x509TemplateDataFlag,
sshTemplateFlag,
sshTemplateDataFlag,
x509MinDurFlag,
x509MaxDurFlag,
x509DefaultDurFlag,
sshUserMinDurFlag,
sshUserMaxDurFlag,
sshUserDefaultDurFlag,
sshHostMinDurFlag,
sshHostMaxDurFlag,
sshHostDefaultDurFlag,
disableRenewalFlag,
enableX509Flag,
enableSSHFlag,
// JWK provisioner flags
cli.BoolFlag{
Name: "create",
Usage: `Create the JWK key pair for the provisioner.`,
},
cli.StringFlag{
Name: "private-key",
Usage: `The <file> containing the JWK private key.`,
},
cli.StringFlag{
Name: "public-key",
Usage: `The <file> containing the JWK public key.`,
},
// OIDC provisioner flags
cli.StringFlag{
Name: "client-id",
Usage: `The <id> used to validate the audience in an OpenID Connect token.`,
},
cli.StringFlag{
Name: "client-secret",
Usage: `The <secret> used to obtain the OpenID Connect tokens.`,
},
cli.StringFlag{
Name: "listen-address",
Usage: `The callback <address> used in the OpenID Connect flow (e.g. \":10000\")`,
},
cli.StringFlag{
Name: "configuration-endpoint",
Usage: `OpenID Connect configuration <url>.`,
},
cli.StringSliceFlag{
Name: "admin",
Usage: `The <email> of an admin user in an OpenID Connect provisioner, this user
will not have restrictions in the certificates to sign. Use the
'--admin' flag multiple times to configure multiple administrators.`,
},
cli.StringSliceFlag{
Name: "remove-admin",
Usage: `Remove the <email> of an admin user in an OpenID Connect provisioner, this user
will not have restrictions in the certificates to sign. Use the
'--admin' flag multiple times to configure multiple administrators.`,
},
cli.StringSliceFlag{
Name: "group",
Usage: `The <group> list used to validate the groups extenstion in an OpenID Connect token.
Use the '--group' flag multiple times to configure multiple groups.`,
},
cli.StringFlag{
Name: "tenant-id",
Usage: `The <tenant-id> used to replace the templatized {tenantid} in the OpenID Configuration.`,
},
// X5C provisioner flags
cli.StringFlag{
Name: "x5c-root",
Usage: `Root certificate (chain) <file> used to validate the signature on X5C
provisioning tokens.`,
},
// ACME provisioner flags
forceCNFlag,
// Cloud provisioner flags
awsAccountFlag,
removeAWSAccountFlag,
azureTenantFlag,
azureResourceGroupFlag,
removeAzureResourceGroupFlag,
gcpServiceAccountFlag,
removeGCPServiceAccountFlag,
gcpProjectFlag,
removeGCPProjectFlag,
instanceAgeFlag,
iidRootsFlag,
disableCustomSANsFlag,
disableTOFUFlag,
flags.AdminCert,
flags.AdminKey,
flags.AdminProvisioner,
flags.AdminSubject,
flags.PasswordFile,
flags.CaURL,
flags.Root,
},
Description: `**step ca provisioner update** updates a provisioner in the CA configuration.
## POSITIONAL ARGUMENTS
<name>
: The name of the provisioner.
## EXAMPLES
Update a JWK provisioner with newly generated keys and a template for x509 certificates:
'''
step beta ca provisioner update cicd --create --x509-template ./templates/example.tpl
'''
Update a JWK provisioner with duration claims:
'''
step beta ca provisioner update cicd --create --x509-min-dur 20m --x509-default-dur 48h --ssh-user-min-dur 17m --ssh-host-default-dur 16h
'''
Update a JWK provisioner with existing keys:
'''
step beta ca provisioner update jane@doe.com --public-key jwk.pub --private-key jwk.priv
'''
Update a JWK provisioner to disable ssh provisioning:
'''
step beta ca provisioner update cicd --ssh=false
'''
Update an OIDC provisioner:
'''
step beta ca provisioner update Google \
--configuration-endpoint https://accounts.google.com/.well-known/openid-configuration
'''
Update an X5C provisioner:
'''
step beta ca provisioner update x5c --x5c-root x5c_ca.crt
'''
Update an ACME provisioner:
'''
step beta ca provisioner update acme --force-cn
'''
Update an K8SSA provisioner:
'''
step beta ca provisioner update kube --public-key key.pub --x509-min-duration 30m
'''
Update an Azure provisioner:
'''
$ step beta ca provisioner update Azure \
--azure-resource-group identity --azure-resource-group accounting
'''
Update an GCP provisioner:
'''
$ step beta ca provisioner update Google \
--disable-custom-sans --gcp-project internal --remove-gcp-project public
'''
Update an AWS provisioner:
document and will allow multiple certificates from the same instance:
'''
$ step beta ca provisioner update Amazon --disable-custom-sans --disable-trust-on-first-use
'''`,
}
}
func updateAction(ctx *cli.Context) (err error) {
if err := errs.NumberOfArguments(ctx, 1); err != nil {
return err
}
args := ctx.Args()
name := args[0]
// Create online client
client, err := cautils.NewAdminClient(ctx)
if err != nil {
return err
}
p, err := client.GetProvisioner(ca.WithProvisionerName(name))
if err != nil {
return err
}
if ctx.IsSet("name") {
p.Name = ctx.String("name")
}
if err := updateTemplates(ctx, p); err != nil {
return err
}
updateClaims(ctx, p)
switch p.Type {
case linkedca.Provisioner_JWK:
err = updateJWKDetails(ctx, p)
case linkedca.Provisioner_ACME:
err = updateACMEDetails(ctx, p)
case linkedca.Provisioner_SSHPOP:
err = updateSSHPOPDetails(ctx, p)
case linkedca.Provisioner_X5C:
err = updateX5CDetails(ctx, p)
case linkedca.Provisioner_K8SSA:
err = updateK8SSADetails(ctx, p)
case linkedca.Provisioner_OIDC:
err = updateOIDCDetails(ctx, p)
case linkedca.Provisioner_AWS:
err = updateAWSDetails(ctx, p)
case linkedca.Provisioner_AZURE:
err = updateAzureDetails(ctx, p)
case linkedca.Provisioner_GCP:
err = updateGCPDetails(ctx, p)
// TODO add SCEP provisioner support.
default:
return fmt.Errorf("unsupported provisioner type %s", p.Type.String())
}
if err != nil {
return err
}
if err = client.UpdateProvisioner(name, p); err != nil {
return err
}
var buf bytes.Buffer
b, err := protojson.Marshal(p)
if err != nil {
return err
}
if err := json.Indent(&buf, b, "", " "); err != nil {
return err
}
fmt.Println(buf.String())
return nil
}
func updateTemplates(ctx *cli.Context, p *linkedca.Provisioner) error {
// Read x509 template if passed
if p.X509Template == nil {
p.X509Template = &linkedca.Template{}
}
if x509TemplateFile := ctx.String("x509-template"); ctx.IsSet("x509-template") {
if x509TemplateFile == "" {
p.X509Template.Template = nil
} else {
b, err := utils.ReadFile(x509TemplateFile)
if err != nil {
return err
}
p.X509Template.Template = b
}
}
if x509TemplateDataFile := ctx.String("x509-template-data"); ctx.IsSet("x509-template-data") {
if x509TemplateDataFile == "" {
p.X509Template.Data = nil
} else {
b, err := utils.ReadFile(x509TemplateDataFile)
if err != nil {
return err
}
p.X509Template.Data = b
}
}
// Read ssh template if passed
if p.SshTemplate == nil {
p.SshTemplate = &linkedca.Template{}
}
if sshTemplateFile := ctx.String("ssh-template"); ctx.IsSet("ssh-template") {
if sshTemplateFile == "" {
p.SshTemplate.Template = nil
} else {
b, err := utils.ReadFile(sshTemplateFile)
if err != nil {
return err
}
p.SshTemplate.Template = b
}
}
if sshTemplateDataFile := ctx.String("ssh-template-data"); ctx.IsSet("ssh-template-data") {
if sshTemplateDataFile == "" {
p.SshTemplate.Data = nil
} else {
b, err := utils.ReadFile(sshTemplateDataFile)
if err != nil {
return err
}
p.SshTemplate.Data = b
}
}
return nil
}
func updateClaims(ctx *cli.Context, p *linkedca.Provisioner) {
if p.Claims == nil {
p.Claims = &linkedca.Claims{}
}
if ctx.IsSet("disable-renewal") {
p.Claims.DisableRenewal = ctx.Bool("disable-renewal")
}
xc := p.Claims.X509
if xc == nil {
xc = &linkedca.X509Claims{}
}
if ctx.IsSet("x509") {
xc.Enabled = ctx.Bool("x509")
}
d := xc.Durations
if d == nil {
d = &linkedca.Durations{}
}
if ctx.IsSet("x509-min-dur") {
d.Min = ctx.String("x509-min-dur")
}
if ctx.IsSet("x509-max-dur") {
d.Max = ctx.String("x509-max-dur")
}
if ctx.IsSet("x509-default-dur") {
d.Default = ctx.String("x509-default-dur")
}
sc := p.Claims.Ssh
if sc == nil {
sc = &linkedca.SSHClaims{}
}
if ctx.IsSet("ssh") {
sc.Enabled = ctx.Bool("ssh")
}
d = sc.UserDurations
if d == nil {
d = &linkedca.Durations{}
}
if ctx.IsSet("ssh-user-min-dur") {
d.Min = ctx.String("ssh-user-min-dur")
}
if ctx.IsSet("ssh-user-max-dur") {
d.Max = ctx.String("ssh-user-max-dur")
}
if ctx.IsSet("ssh-user-default-dur") {
d.Default = ctx.String("ssh-user-default-dur")
}
d = sc.HostDurations
if d == nil {
d = &linkedca.Durations{}
}
if ctx.IsSet("ssh-host-min-dur") {
d.Min = ctx.String("ssh-host-min-dur")
}
if ctx.IsSet("ssh-host-max-dur") {
d.Max = ctx.String("ssh-host-max-dur")
}
if ctx.IsSet("ssh-host-default-dur") {
d.Default = ctx.String("ssh-host-default-dur")
}
}
func updateJWKDetails(ctx *cli.Context, p *linkedca.Provisioner) error {
data, ok := p.Details.GetData().(*linkedca.ProvisionerDetails_JWK)
if !ok {
return errors.New("error casting details to ACME type")
}
details := data.JWK
var (
err error
password string
)
if passwordFile := ctx.String("password-file"); len(passwordFile) > 0 {
password, err = utils.ReadStringPasswordFromFile(passwordFile)
if err != nil {
return err
}
}
var (
jwk *jose.JSONWebKey
jwe *jose.JSONWebEncryption
)
if ctx.Bool("create") {
if ctx.IsSet("public-key") {
return errs.IncompatibleFlag(ctx, "create", "public-key")
}
if ctx.IsSet("private-key") {
return errs.IncompatibleFlag(ctx, "create", "private-key")
}
pass, err := ui.PromptPasswordGenerate("Please enter a password to encrypt the provisioner private key? [leave empty and we'll generate one]", ui.WithValue(password))
if err != nil {
return err
}
jwk, jwe, err = jose.GenerateDefaultKeyPair(pass)
if err != nil {
return err
}
} else {
if ctx.IsSet("public-key") {
jwkFile := ctx.String("public-key")
jwk, err = jose.ParseKey(jwkFile)
if err != nil {
return errs.FileError(err, jwkFile)
}
// Only use asymmetric cryptography
if _, ok := jwk.Key.([]byte); ok {
return errors.New("invalid JWK: a symmetric key cannot be used as a provisioner")
}
// Create kid if not present
if len(jwk.KeyID) == 0 {
jwk.KeyID, err = jose.Thumbprint(jwk)
if err != nil {
return err
}
}
}
if ctx.IsSet("private-key") {
jwkFile := ctx.String("private-key")
b, err := ioutil.ReadFile(jwkFile)
if err != nil {
return errors.Wrapf(err, "error reading %s", jwkFile)
}
// Attempt to parse private key as Encrypted JSON.
// If this operation fails then either,
// 1. the key is not encrypted
// 2. the key has an invalid format
//
// Attempt to parse as decrypted private key.
jwe, err = jose.ParseEncrypted(string(b))
if err != nil {
privjwk, err := jose.ParseKey(jwkFile)
if err != nil {
return errs.FileError(err, jwkFile)
}
if privjwk.IsPublic() {
return errors.New("invalid jwk: private-key is a public key")
}
// Encrypt JWK
opts := []jose.Option{}
if ctx.IsSet("password-file") {
opts = append(opts, jose.WithPasswordFile(ctx.String("password-file")))
}
jwe, err = jose.EncryptJWK(privjwk, opts...)
if err != nil {
return err
}
}
}
}
if jwk != nil {
jwkPubBytes, err := jwk.MarshalJSON()
if err != nil {
return errors.Wrap(err, "error marshaling JWK")
}
details.PublicKey = jwkPubBytes
}
if jwe != nil {
jwePrivStr, err := jwe.CompactSerialize()
if err != nil {
return errors.Wrap(err, "error serializing JWE")
}
details.EncryptedPrivateKey = []byte(jwePrivStr)
}
return nil
}
func updateACMEDetails(ctx *cli.Context, p *linkedca.Provisioner) error {
data, ok := p.Details.GetData().(*linkedca.ProvisionerDetails_ACME)
if !ok {
return errors.New("error casting details to ACME type")
}
details := data.ACME
if ctx.IsSet("force-cn") {
details.ForceCn = ctx.Bool("force-cn")
}
return nil
}
func updateSSHPOPDetails(ctx *cli.Context, p *linkedca.Provisioner) error {
return nil
}
func updateX5CDetails(ctx *cli.Context, p *linkedca.Provisioner) error {
data, ok := p.Details.GetData().(*linkedca.ProvisionerDetails_X5C)
if !ok {
return errors.New("error casting details to X5C type")
}
details := data.X5C
if ctx.IsSet("x5c-root") {
x5cRootFile := ctx.String("x5c-root")
roots, err := pemutil.ReadCertificateBundle(x5cRootFile)
if err != nil {
return errors.Wrapf(err, "error loading X5C Root certificates from %s", x5cRootFile)
}
var rootBytes [][]byte
for _, r := range roots {
if r.KeyUsage&x509.KeyUsageCertSign == 0 {
return errors.Errorf("error: certificate with common name '%s' cannot be "+
"used as an X5C root certificate.\n\n"+
"X5C provisioner root certificates must have the 'Certificate Sign' key "+
"usage extension.", r.Subject.CommonName)
}
rootBytes = append(rootBytes, pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE",
Bytes: r.Raw,
}))
}
details.Roots = rootBytes
}
return nil
}
func updateK8SSADetails(ctx *cli.Context, p *linkedca.Provisioner) error {
data, ok := p.Details.GetData().(*linkedca.ProvisionerDetails_K8SSA)
if !ok {
return errors.New("error casting details to K8SSA type")
}
details := data.K8SSA
if ctx.IsSet("public-key") {
pemKeysF := ctx.String("public-key")
pemKeysB, err := ioutil.ReadFile(pemKeysF)
if err != nil {
return errors.Wrap(err, "error reading pem keys")
}
var (
block *pem.Block
rest = pemKeysB
pemKeys = []interface{}{}
)
for rest != nil {
block, rest = pem.Decode(rest)
if block == nil {
break
}
key, err := pemutil.ParseKey(pem.EncodeToMemory(block))
if err != nil {
return errors.Wrapf(err, "error parsing public key from %s", pemKeysF)
}
switch q := key.(type) {
case *rsa.PublicKey, *ecdsa.PublicKey, ed25519.PublicKey:
default:
return errors.Errorf("Unexpected public key type %T in %s", q, pemKeysF)
}
pemKeys = append(pemKeys, key)
}
var pubKeyBytes [][]byte
for _, k := range pemKeys {
blk, err := pemutil.Serialize(k)
if err != nil {
return errors.Wrap(err, "error serializing pem key")
}
pubKeyBytes = append(pubKeyBytes, pem.EncodeToMemory(blk))
}
details.PublicKeys = pubKeyBytes
}
return nil
}
func updateOIDCDetails(ctx *cli.Context, p *linkedca.Provisioner) error {
data, ok := p.Details.GetData().(*linkedca.ProvisionerDetails_OIDC)
if !ok {
return errors.New("error casting details to OIDC type")
}
details := data.OIDC
if ctx.IsSet("client-id") {
details.ClientId = ctx.String("client-id")
}
if ctx.IsSet("client-secret") {
details.ClientSecret = ctx.String("client-secret")
}
if ctx.IsSet("remove-admin") {
details.Admins = removeElements(details.Admins, ctx.StringSlice("remove-admin"))
}
if ctx.IsSet("admin") {
details.Admins = append(details.Admins, ctx.StringSlice("admin")...)
}
if ctx.IsSet("domain") {
details.Domains = ctx.StringSlice("domain")
}
if ctx.IsSet("group") {
details.Groups = ctx.StringSlice("group")
}
if ctx.IsSet("listen-address") {
details.ListenAddress = ctx.String("listen-address")
}
if ctx.IsSet("tenant-id") {
details.TenantId = ctx.String("tenant-id")
}
if ctx.IsSet("configuration-endpoint") {
ce := ctx.String("configuration-endpoint")
u, err := url.Parse(ce)
if err != nil || (u.Scheme != "https" && u.Scheme != "http") {
return errs.InvalidFlagValue(ctx, "configuration-endpoint", ce, "")
}
details.ConfigurationEndpoint = ce
}
return nil
}
func updateAWSDetails(ctx *cli.Context, p *linkedca.Provisioner) error {
data, ok := p.Details.GetData().(*linkedca.ProvisionerDetails_AWS)
if !ok {
return errors.New("error casting details to OIDC type")
}
details := data.AWS
var err error
if ctx.IsSet("instance-age") {
details.InstanceAge, err = parseIntaceAge(ctx)
if err != nil {
return err
}
}
if ctx.IsSet("disable-custom-sans") {
details.DisableCustomSans = ctx.Bool("disable-custom-sans")
}
if ctx.IsSet("disable-trust-on-first-use") {
details.DisableCustomSans = ctx.Bool("disable-trust-on-first-use")
}
if ctx.IsSet("remove-aws-account") {
details.Accounts = removeElements(details.Accounts, ctx.StringSlice("remove-aws-account"))
}
if ctx.IsSet("aws-account") {
details.Accounts = append(details.Accounts, ctx.StringSlice("add-aws-account")...)
}
return nil
}
func updateAzureDetails(ctx *cli.Context, p *linkedca.Provisioner) error {
data, ok := p.Details.GetData().(*linkedca.ProvisionerDetails_Azure)
if !ok {
return errors.New("error casting details to OIDC type")
}
details := data.Azure
if ctx.IsSet("azure-tenant") {
details.TenantId = ctx.String("azure-tenant")
}
if ctx.IsSet("disable-custom-sans") {
details.DisableCustomSans = ctx.Bool("disable-custom-sans")
}
if ctx.IsSet("disable-trust-on-first-use") {
details.DisableCustomSans = ctx.Bool("disable-trust-on-first-use")
}
if ctx.IsSet("remove-azure-resource-group") {
details.ResourceGroups = removeElements(details.ResourceGroups, ctx.StringSlice("remove-azure-resource-group"))
}
if ctx.IsSet("azure-resource-group") {
details.ResourceGroups = append(details.ResourceGroups, ctx.StringSlice("add-azure-resource-group")...)
}
return nil
}
func updateGCPDetails(ctx *cli.Context, p *linkedca.Provisioner) error {
data, ok := p.Details.GetData().(*linkedca.ProvisionerDetails_GCP)
if !ok {
return errors.New("error casting details to OIDC type")
}
details := data.GCP
var err error
if ctx.IsSet("instance-age") {
details.InstanceAge, err = parseIntaceAge(ctx)
if err != nil {
return err
}
}
if ctx.IsSet("disable-custom-sans") {
details.DisableCustomSans = ctx.Bool("disable-custom-sans")
}
if ctx.IsSet("disable-trust-on-first-use") {
details.DisableCustomSans = ctx.Bool("disable-trust-on-first-use")
}
if ctx.IsSet("remove-gcp-service-account") {
details.ServiceAccounts = removeElements(details.ServiceAccounts, ctx.StringSlice("remove-gcp-service-account"))
}
if ctx.IsSet("gcp-service-account") {
details.ServiceAccounts = append(details.ServiceAccounts, ctx.StringSlice("add-gcp-service-account")...)
}
if ctx.IsSet("remove-gcp-project") {
details.ProjectIds = removeElements(details.ProjectIds, ctx.StringSlice("gcp-project"))
}
if ctx.IsSet("gcp-project") {
details.ServiceAccounts = append(details.ProjectIds, ctx.StringSlice("add-gcp-project")...)
}
return nil
}

View File

@@ -40,11 +40,11 @@ func createCommand() cli.Command {
Action: command.ActionFunc(createAction),
Usage: "create a certificate or certificate signing request",
UsageText: `**step certificate create** <subject> <crt-file> <key-file>
[**--csr**] [**--profile**=<profile>] [**--template**=<path>]
[**--csr**] [**--profile**=<profile>] [**--template**=<file>]
[**--not-before**=<duration>] [**--not-after**=<duration>]
[**--password-file**=<path>] [**--ca**=<issuer-cert>]
[**--ca-key**=<issuer-key>] [**--ca-password-file**=<path>]
[**--san**=<SAN>] [**--bundle**] [**--key**=<path>]
[**--password-file**=<file>] [**--ca**=<issuer-cert>]
[**--ca-key**=<issuer-key>] [**--ca-password-file**=<file>]
[**--san**=<SAN>] [**--bundle**] [**--key**=<file>]
[**--kty**=<type>] [**--curve**=<curve>] [**--size**=<size>]
[**--no-password**] [**--insecure**]`,
Description: `**step certificate create** generates a certificate or a
@@ -341,11 +341,11 @@ $ step certificate create --csr --template csr.tpl --san coyote@acme.corp \
},
cli.StringFlag{
Name: "template",
Usage: `The certificate template <path>, a JSON representation of the certificate to create.`,
Usage: `The certificate template <file>, a JSON representation of the certificate to create.`,
},
cli.StringFlag{
Name: "password-file",
Usage: `The <path> to the file containing the password to
Usage: `The <file> to the file containing the password to
encrypt the new private key or decrypt the user submitted private key.`,
},
cli.StringFlag{
@@ -358,12 +358,12 @@ encrypt the new private key or decrypt the user submitted private key.`,
},
cli.StringFlag{
Name: "ca-password-file",
Usage: `The <path> to the file containing the password to
Usage: `The <file> to the file containing the password to
decrypt the CA private key.`,
},
cli.StringFlag{
Name: "key",
Usage: "The <path> of the private key to use instead of creating a new one (PEM file).",
Usage: "The <file> of the private key to use instead of creating a new one (PEM file).",
},
cli.BoolFlag{
Name: "no-password",

View File

@@ -143,7 +143,7 @@ func getFingerprintFormat(format string) (x509util.FingerprintEncoding, error) {
case "base64":
return x509util.Base64Fingerprint, nil
case "base64url", "base64-url":
return x509util.Base64UrlFingerprint, nil
return x509util.Base64URLFingerprint, nil
}
return x509util.HexFingerprint, errors.Errorf("error parsing fingerprint format: '%s' is not a valid certificate fingerprint format", format)
}

View File

@@ -1,8 +1,9 @@
package certificate
import (
"github.com/smallstep/cli/crypto/x509util"
"testing"
"github.com/smallstep/cli/crypto/x509util"
)
func TestGetFingerprintFormat(t *testing.T) {
@@ -36,7 +37,7 @@ func TestGetFingerprintFormat(t *testing.T) {
args{
"base64Url",
},
x509util.Base64UrlFingerprint,
x509util.Base64URLFingerprint,
false,
},
{
@@ -44,7 +45,7 @@ func TestGetFingerprintFormat(t *testing.T) {
args{
"base64-URL",
},
x509util.Base64UrlFingerprint,
x509util.Base64URLFingerprint,
false,
},
{

View File

@@ -207,11 +207,7 @@ func doLoginIfNeeded(ctx *cli.Context, subject string) error {
}
// Add certificate and private key to agent
if err := agent.AddCertificate(subject, resp.Certificate.Certificate, priv); err != nil {
return err
}
return nil
return agent.AddCertificate(subject, resp.Certificate.Certificate, priv)
}
func getBastion(ctx *cli.Context, user, host string) (*api.SSHBastionResponse, error) {

View File

@@ -22,12 +22,16 @@ func Fingerprint(cert *x509.Certificate) string {
return EncodedFingerprint(cert, HexFingerprint)
}
// FingerprintEncoding represents the fingerprint encoding type.
type FingerprintEncoding int
const (
// HexFingerprint represents hex encoding of fingerprint.
HexFingerprint FingerprintEncoding = iota
// Base64Fingerprint represents base64 encoding of fingerprint.
Base64Fingerprint
Base64UrlFingerprint
// Base64URLFingerprint represents base64URL encoding of fingerprint.
Base64URLFingerprint
)
// EncodedFingerprint returns an encoded the SHA-256 fingerprint of the certificate. Defaults to hex encoding
@@ -43,7 +47,7 @@ func EncodedFingerprint(cert *x509.Certificate, encoding FingerprintEncoding) st
switch encoding {
case Base64Fingerprint:
return base64.StdEncoding.EncodeToString(src)
case Base64UrlFingerprint:
case Base64URLFingerprint:
return base64.URLEncoding.EncodeToString(src)
}
// should not get here

View File

@@ -38,7 +38,7 @@ func TestEncodedFingerprint(t *testing.T) {
}{
{"hex", "test_files/ca.crt", HexFingerprint, "6908751f68290d4573ae0be39a98c8b9b7b7d4e8b2a6694b7509946626adfe98"},
{"base64", "test_files/ca.crt", Base64Fingerprint, "aQh1H2gpDUVzrgvjmpjIube31OiypmlLdQmUZiat/pg="},
{"base64url", "test_files/ca.crt", Base64UrlFingerprint, "aQh1H2gpDUVzrgvjmpjIube31OiypmlLdQmUZiat_pg="},
{"base64url", "test_files/ca.crt", Base64URLFingerprint, "aQh1H2gpDUVzrgvjmpjIube31OiypmlLdQmUZiat_pg="},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

View File

@@ -257,7 +257,7 @@ func Test_base_CreateCertificate(t *testing.T) {
extKeyUsageExt.Id = asn1.ObjectIdentifier{2, 5, 29, 37}
extKeyUsageExt.Critical = false
var oids []asn1.ObjectIdentifier
var eku []x509.ExtKeyUsage = []x509.ExtKeyUsage{
var eku = []x509.ExtKeyUsage{
x509.ExtKeyUsageServerAuth,
x509.ExtKeyUsageClientAuth,
x509.ExtKeyUsageMicrosoftKernelCodeSigning,

View File

@@ -145,6 +145,19 @@ as "300ms", "-1.5h" or "2h45m". Valid time units are "ns", "us" (or "µs"), "ms"
Usage: "The provisioner <name> to use.",
}
// AdminProvisioner is a cli.Flag used to pass the CA Admin provisioner to use.
AdminProvisioner = cli.StringFlag{
Name: "admin-provisioner,admin-issuer",
Usage: "The provisioner <name> to use for generating admin credentials.",
}
// AdminSubject is a cli.Flag used to pass the admin subject to use when generating
// admin credentials.
AdminSubject = cli.StringFlag{
Name: "admin-subject,admin-name",
Usage: "The admin <subject> to use for generating admin credentials.",
}
// ProvisionerPasswordFile is a cli.Flag used to pass the password file to
// decrypt the generating key.
ProvisionerPasswordFile = cli.StringFlag{
@@ -189,6 +202,20 @@ $STEPPATH/config/ca.json`,
Value: filepath.Join(config.StepPath(), "config", "ca.json"),
}
// AdminCert is a cli.Flag used to pass the x5c header certificate for a JWT.
AdminCert = cli.StringFlag{
Name: "admin-cert",
Usage: "Admin certificate (<chain>) in PEM format to store in the 'x5c' header of a JWT.",
}
// AdminKey is a cli.Flag used to pass the private key (corresponding to the x5c-cert)
// that is used to sign the token.
AdminKey = cli.StringFlag{
Name: "admin-key",
Usage: `Private key <path>, used to sign a JWT, corresponding to the admin certificate that will
be stored in the 'x5c' header.`,
}
// X5cCert is a cli.Flag used to pass the x5c header certificate for a JWT.
X5cCert = cli.StringFlag{
Name: "x5c-cert",

31
go.mod
View File

@@ -3,34 +3,49 @@ module github.com/smallstep/cli
go 1.13
require (
cloud.google.com/go v0.70.0 // indirect
github.com/Microsoft/go-winio v0.4.14
github.com/ThalesIgnite/crypto11 v1.2.4 // indirect
github.com/ThomasRooney/gexpect v0.0.0-20161231170123-5482f0350944
github.com/aws/aws-sdk-go v1.30.29 // indirect
github.com/boombuler/barcode v1.0.0 // indirect
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e
github.com/corpix/uarand v0.1.1 // indirect
github.com/go-chi/chi v4.0.2+incompatible // indirect
github.com/go-kit/kit v0.10.0 // indirect
github.com/go-piv/piv-go v1.7.0 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golangci/golangci-lint v1.24.0 // indirect
github.com/google/uuid v1.1.2
github.com/icrowley/fake v0.0.0-20180203215853-4178557ae428
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
github.com/manifoldco/promptui v0.8.0
github.com/micromdm/scep/v2 v2.0.0 // indirect
github.com/newrelic/go-agent v2.15.0+incompatible // indirect
github.com/pkg/errors v0.9.1
github.com/pquerna/otp v1.0.0
github.com/rs/xid v1.2.1 // indirect
github.com/samfoo/ansi v0.0.0-20160124022901-b6bd2ded7189
github.com/shurcooL/sanitized_anchor_name v1.0.0
github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262
github.com/smallstep/certificates v0.15.16
github.com/smallstep/certinfo v1.5.0
github.com/smallstep/nosql v0.3.6 // indirect
github.com/smallstep/truststore v0.9.6
github.com/smallstep/zcrypto v0.0.0-20200203191936-fbc32cf76bce
github.com/smallstep/zlint v0.0.0-20180727184541-d84eaafe274f
github.com/stretchr/testify v1.7.0
github.com/urfave/cli v1.22.4
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1
go.step.sm/crypto v0.8.3
go.step.sm/cli-utils v0.4.1 // indirect
go.step.sm/crypto v0.9.0
go.step.sm/linkedca v0.0.0-20210611183751-27424aae8d25
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a
golang.org/x/net v0.0.0-20210525063256-abc453219eb5
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c
golang.org/x/term v0.0.0-20210503060354-a79de5458b56
google.golang.org/protobuf v1.26.0
gopkg.in/square/go-jose.v2 v2.5.1
software.sslmate.com/src/go-pkcs12 v0.0.0-20201103104416-57fc603b7f52
)
@@ -41,8 +56,12 @@ require (
// interfaces.
//
// For more information see https://github.com/etcd-io/etcd/issues/12124
replace google.golang.org/grpc => google.golang.org/grpc v1.29.1
replace google.golang.org/grpc => google.golang.org/grpc v1.32.0
replace github.com/smallstep/certificates => ../certificates
//replace go.step.sm/linkedca => ../linkedca
//replace go.step.sm/cli-utils => ../cli-utils
// replace github.com/smallstep/certificates => ../certificates
// replace github.com/smallstep/certinfo => ../certinfo
//replace go.step.sm/crypto => ../crypto

244
go.sum
View File

@@ -24,30 +24,41 @@ cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNF
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0 h1:PQcPefKFdaIzjQFbiyOgAqyx8q5djaE7x9Sqe712DPA=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0 h1:/May9ojXjRkPBNVrq+oWLqmWCkr4OU5uRY29bu0mRyQ=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1 h1:ukjixP1wl0LpnZ6LWtZJ0mX5tBmjp1f8Sqer8Z2OMUU=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
contrib.go.opencensus.io/exporter/stackdriver v0.12.1 h1:Dll2uFfOVI3fa8UzsHyP6z0M6fEc9ZTAMo+Y3z282Xg=
contrib.go.opencensus.io/exporter/stackdriver v0.12.1/go.mod h1:iwB6wGarfphGGe/e5CWqyUk/cLzKnWsOKPVW3no6OTw=
contrib.go.opencensus.io/resource v0.1.1 h1:4r2CANuYhKGmYWP02+5E94rLRcS/YeD+KlxSrOsMxk0=
contrib.go.opencensus.io/resource v0.1.1/go.mod h1:F361eGI91LCmW1I/Saf+rX0+OFcigGlFvXwEGEnkRLA=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M=
github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ=
github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/Masterminds/glide v0.13.2 h1:M5MOH04TyRiMBVeWHbifqTpnauxWINIubTCOkhXh+2g=
github.com/Masterminds/glide v0.13.2/go.mod h1:STyF5vcenH/rUqTEv+/hBXlSTo7KYwg2oc2f4tzPWic=
github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg=
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
@@ -57,6 +68,7 @@ github.com/Masterminds/semver/v3 v3.1.0 h1:Y2lUDsFKVRSYGojLJ1yLxSXdMmMYTYls0rCvo
github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/Masterminds/sprig/v3 v3.1.0 h1:j7GpgZ7PdFqNsmncycTHsLmVPf5/3wJtlgW9TNDYD9Y=
github.com/Masterminds/sprig/v3 v3.1.0/go.mod h1:ONGMf7UfYGAbMXCZmQLy8x3lCDIPrEZE/rU8pmrbihA=
github.com/Masterminds/vcs v1.13.0 h1:USF5TvZGYgIpcbNAEMLfFhHqP08tFZVlUVrmTSpqnyA=
github.com/Masterminds/vcs v1.13.0/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA=
github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
@@ -65,32 +77,48 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE
github.com/OpenPeeDeeP/depguard v1.0.0/go.mod h1:7/4sitnI9YlQgTLLk734QlzXT8DuHVnAyztLplQjk+o=
github.com/OpenPeeDeeP/depguard v1.0.1 h1:VlW4R6jmBIv3/u1JNlawEvJMM4J+dPORPaZasQee8Us=
github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM=
github.com/Shopify/sarama v1.19.0 h1:9oksLxC6uxVPHPVYUmq6xhr1BOF/hHobWH2UzO67z1s=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8=
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/ThalesIgnite/crypto11 v1.2.4 h1:3MebRK/U0mA2SmSthXAIZAdUA9w8+ZuKem2O6HuR1f8=
github.com/ThalesIgnite/crypto11 v1.2.4/go.mod h1:ILDKtnCKiQ7zRoNxcp36Y1ZR8LBPmR2E23+wTQe/MlE=
github.com/ThomasRooney/gexpect v0.0.0-20161231170123-5482f0350944 h1:CjexZrggt4RldpEUXFZf52vSO3cnmFaqW6B4wADj05Q=
github.com/ThomasRooney/gexpect v0.0.0-20161231170123-5482f0350944/go.mod h1:sPML5WwI6oxLRLPuuqbtoOKhtmpVDCYtwsps+I+vjIY=
github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE=
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 h1:rFw4nCn9iMW+Vajsk51NtYIcwSTkXr+JGrMd36kTDJw=
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/apache/thrift v0.13.0 h1:5hryIiq9gtn+MiLVn0wP37kb/uTeRZgN08WoCsAhIhI=
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 h1:G1bPvciwNyF7IUmKXNt9Ak3m6u9DE1rF+RmtIkBpVdA=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 h1:BUAU3CGlLvorLI26FmByPp2eC2qla6E1Tw+scpcg/to=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a h1:pv34s756C4pEXnjgPfGYgdhg/ZdajGhyOvzx8k+23nw=
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf h1:eg0MeVzsP1G42dRafH3vf+al2vQIJU0YHX+1Tw87oco=
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/aws/aws-lambda-go v1.13.3 h1:SuCy7H3NLyp+1Mrfp+m80jcbi9KYWAs9/BXwppwRDzY=
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
github.com/aws/aws-sdk-go v1.19.18/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.30.29 h1:NXNqBS9hjOCpDL8SyCyl38gZX3LLLunKOJc5E7vJ8P0=
github.com/aws/aws-sdk-go v1.30.29/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
github.com/aws/aws-sdk-go-v2 v0.18.0 h1:qZ+woO4SamnH/eEbjM2IDLhRNwIwND/RQyVlBLp3Jqg=
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
@@ -98,14 +126,18 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
github.com/bombsimon/wsl/v2 v2.0.0 h1:+Vjcn+/T5lSrO8Bjzhk4v14Un/2UyCA1E3V5j9nwTkQ=
github.com/bombsimon/wsl/v2 v2.0.0/go.mod h1:mf25kr/SqFEPhhcxW1+7pxzGlW+hIl/hYTKY95VwV8U=
github.com/boombuler/barcode v1.0.0 h1:s1TvRnXwL2xJRaccrdcBQMZxq6X7DvsMogtmJeHDdrc=
github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/casbin/casbin/v2 v2.1.2 h1:bTwon/ECRx9dwBy2ewRVr5OiqjeXSGiTUY74sDPQi/g=
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
@@ -117,16 +149,22 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5O
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec h1:EdRZT3IeKQmfCSrgo8SZ8V3MEnskuJP0wCYNpe+aiXo=
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f h1:WBZRG4aNOuI15bLRrCgN8fCq8E5Xuty6jGbmSNEvSsU=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa h1:OaNxuTZr7kxeODyLWsRMC+OD03aFUH+mW6r2d+MWa5Y=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/codegangsta/cli v1.20.0 h1:iX1FXEgwzd5+XN6wk5cVHOGQj6Q3Dcp20lUeS4lHNTw=
github.com/codegangsta/cli v1.20.0/go.mod h1:/qJNoX69yVSKu5o4jLyXAENLRyk1uhi7zkbQ3slBdOA=
github.com/coreos/bbolt v1.3.2 h1:wZwiHHUieZCquLkDL0B8UhzreNWsPHooDAG3q34zk0s=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.13+incompatible h1:8F3hqu9fGYLBifCmRCJsicFqDx/D68Rt3q1JMazcgBQ=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible h1:bXhRBIXoTm9BYHS3gE0TtQuyNZyeEMux2sDi4oo5YOo=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
@@ -161,20 +199,29 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y=
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954 h1:RMLoZVzv4GliuWafOuPuQDKSm1SJph7uCRnnS61JAn4=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/eapache/go-resiliency v1.1.0 h1:1NtRmCAqadE2FN4ZcN6g90TP3uk8cg9rn9eNK2197aU=
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/envoyproxy/go-control-plane v0.9.4 h1:rEvIZUSZ3fx39WIi3JkQqQBitGwpELBIYWeBVh6wn+E=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.6.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db h1:gb2Z18BhTPJPpLQWj4T+rfKHYCHxRHCtRxhKKjRidVw=
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8 h1:a9ENSRDFBUPkJ5lCgVZh26+ZbGyoVJG7yb5SSzF5H54=
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
@@ -185,8 +232,10 @@ github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxm
github.com/go-critic/go-critic v0.3.5-0.20190526074819-1df300866540/go.mod h1:+sE8vrLDS2M0pZkBk0wy6+nLdKexVDrl/jBqQOTDThA=
github.com/go-critic/go-critic v0.4.1 h1:4DTQfT1wWwLg/hzxwD9bkdhDQrdJtxe6DUTadPlrIeE=
github.com/go-critic/go-critic v0.4.1/go.mod h1:7/14rZGnZbY6E38VEGk2kVhoq6itzc1E68facVDK23g=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-kit/kit v0.4.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
@@ -199,7 +248,9 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E=
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
github.com/go-piv/piv-go v1.7.0 h1:rfjdFdASfGV5KLJhSjgpGJ5lzVZVtRWn8ovy/H9HQ/U=
github.com/go-piv/piv-go v1.7.0/go.mod h1:ON2WvQncm7dIkCQ7kYJs+nc3V4jHGfrrJnSF8HKy7Gk=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
@@ -218,6 +269,7 @@ github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CY
github.com/go-toolsmith/astfmt v0.0.0-20180903215011-8f8ee99c3086/go.mod h1:mP93XdblcopXwlyN4X4uodxXQhldPGZbcEJIimQHrkg=
github.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k=
github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw=
github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21 h1:wP6mXeB2V/d1P1K7bZ5vDUO3YqEzcvOREOxZPEu3gVI=
github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU=
github.com/go-toolsmith/astp v0.0.0-20180903215135-0af7e3c24f30/go.mod h1:SV2ur98SGypH1UjcPpCatrV5hPazG6+IfNHbkDXBRrk=
github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg=
@@ -269,8 +321,6 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
@@ -286,6 +336,7 @@ github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6 h1:YYWNAGTKWhKpc
github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6/go.mod h1:DbHgvLiFKX1Sh2T1w8Q/h4NAI8MHIpzCdnBUDTXU3I0=
github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613 h1:9kfjN3AdxcbsZBf8NjltjWihK2QfBBBZuv91cMFfDHw=
github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8=
github.com/golangci/go-tools v0.0.0-20190318055746-e32c54105b7c h1:/7detzz5stiXWPzkTlPTzkBEIIE4WGpppBJYjKqBiPI=
github.com/golangci/go-tools v0.0.0-20190318055746-e32c54105b7c/go.mod h1:unzUULGw35sjyOYjUt0jMTXqHlZPpPc6e+xfO4cd6mM=
github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3 h1:pe9JHs3cHHDQgOFXJJdYkK6fLz2PWyYtP4hthoCMvs8=
github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3/go.mod h1:JXrF4TWy4tXYn62/9x8Wm/K/dm06p8tCKwFRDPZG/1o=
@@ -297,6 +348,7 @@ github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u
github.com/golangci/golangci-lint v1.17.2-0.20190910081718-bad04bb7378f/go.mod h1:kaqo8l0OZKYPtjNmG4z4HrWLgcYNIJ9B9q3LWri9uLg=
github.com/golangci/golangci-lint v1.24.0 h1:OcmSTTMPqI/VT4GvN1fKuE9NX15dDXIwolO0l08334U=
github.com/golangci/golangci-lint v1.24.0/go.mod h1:yIqiAZ2SSQqg+1JeFlAdvEWjGVz4uu5jr4lrciqA1gE=
github.com/golangci/gosec v0.0.0-20190211064107-66fb7fc33547 h1:fUdgm/BdKvwOHxg5AhNbkNRp2mSy8sxTXyBVs/laQHo=
github.com/golangci/gosec v0.0.0-20190211064107-66fb7fc33547/go.mod h1:0qUabqiIQgfmlAmulqxyiGkkyF6/tOGSnY2cnPVwrzU=
github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc h1:gLLhTLMk2/SutryVJ6D4VZCU3CUqr8YloG7FPIBWFpI=
github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc/go.mod h1:e5tpTHCfVze+7EpLEozzMB3eafxo2KT5veNg1k6byQU=
@@ -326,13 +378,13 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0 h1:pMen7vLs8nvgEYhywH3KDWJIJTeEr2ULsVWHWYHQyBs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
@@ -345,13 +397,13 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201009210932-67992a1a5a35 h1:WL9iUw2tSwvaCb3++2fMsg2dAmpZd5AykgFftgfHETc=
github.com/google/pprof v0.0.0-20201009210932-67992a1a5a35/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/trillian v1.2.2-0.20190612132142-05461f4df60a h1:Bn71r2jt5ObayLNUtMlCzNlKiw7o59esC9sz9ENjSe0=
github.com/google/trillian v1.2.2-0.20190612132142-05461f4df60a/go.mod h1:YPmUVn5NGwgnDUgqlVyFGMTgaWlnSvH7W5p+NdOG8UA=
github.com/google/trillian-examples v0.0.0-20190603134952-4e75ba15216c h1:dv2J28D109qglM6VfNzAXZ7VddBojviT5oMSs1yeDUY=
github.com/google/trillian-examples v0.0.0-20190603134952-4e75ba15216c/go.mod h1:WgL3XZ3pA8/9cm7yxqWrZE6iZkESB2ItGxy5Fo6k2lk=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -363,15 +415,18 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/mux v1.4.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3 h1:JVnpOZS+qxli+rgVl98ILOXVNbW+kb5wcxeGx8ShUIw=
github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
github.com/groob/finalizer v0.0.0-20170707115354-4c2ed49aabda h1:5ikpG9mYCMFiZX0nkxoV6aU2IpCHPdws3gCNgdZeEV0=
github.com/groob/finalizer v0.0.0-20170707115354-4c2ed49aabda/go.mod h1:MyndkAZd5rUMdNogn35MWXBX1UiBigrU8eTj8DoAC2c=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4 h1:z53tR0945TRRQO/fLEVPI6SMv7ZflF0TEaTAoU7tOzg=
@@ -381,35 +436,55 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.9.5 h1:UImYN5qQ8tuGpGE16ZmjvcTtTw24zw1QAp/SlnNrZhI=
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/consul/api v1.3.0 h1:HXNYlRkkM/t+Y/Yhxtwcy02dlYwIaoxzvxPnS+cqy78=
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
github.com/hashicorp/consul/sdk v0.3.0 h1:UOxjlb4xVNF93jak1mzzoBatyFju9nrkxpVwIp/QqxQ=
github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-rootcerts v1.0.0 h1:Rqb66Oo1X/eSV1x66xbDccZjhJigjg0+e82kpwzSwCI=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E=
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go.net v0.0.1 h1:sNCoNyDEvN1xa+X0baata4RdcpKwcMS6DH+xwfqPgjw=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.0 h1:WhIgCr5a7AaVH6jPUwjtRuuE7/RDufnUvzIr48smyxs=
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3 h1:EmmoJme1matNzb+hMpDuR/0sbJSUisxyqBGG676r31M=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2 h1:YZ7UKsJv+hKjqGVUUbtE3HNj79Eln2oQ75tniF6iPt0=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huandu/xstrings v1.3.1 h1:4jgBlKK6tLKFvO8u5pmYjG91cqytmDCDvGh7ECVFfFs=
github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/hudl/fargo v1.3.0 h1:0U6+BtN6LhaYuTnIJq4Wyq5cpn6O2kWrxAtcqBmYY6w=
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639 h1:mV02weKRL81bEnm8A0HT1/CAelMQDBuQIfLw8n+d6xI=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/icrowley/fake v0.0.0-20180203215853-4178557ae428 h1:Mo9W14pwbO9VfRe+ygqZ8dFbPpoIK1HFrG/zjTuQ+nc=
github.com/icrowley/fake v0.0.0-20180203215853-4178557ae428 h1:Mo9W14pwbO9VfRe+ygqZ8dFbPpoIK1HFrG/zjTuQ+nc=
@@ -419,7 +494,9 @@ github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ=
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d h1:/WZQPMZNsjZ7IlCpsLGdQBINg5bxKQ1K1sh6awxLtkA=
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a h1:GmsqmapfzSJkm28dhRoHz2tLRbJmqhU86IPgBtN3mmk=
github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a/go.mod h1:xRskid8CManxVta/ALEhJha/pweKBaVG6fWgc0yH25s=
@@ -428,6 +505,7 @@ github.com/jirfag/go-printf-func-name v0.0.0-20191110105641-45db9963cdd3/go.mod
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc=
github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
github.com/jmoiron/sqlx v1.2.1-0.20190826204134-d7d95172beb5 h1:lrdPtrORjGv1HbbEvKWDUAy97mPpFm4B8hp77tcCUJY=
github.com/jmoiron/sqlx v1.2.1-0.20190826204134-d7d95172beb5/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
@@ -436,26 +514,33 @@ github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u
github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok=
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU=
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU=
github.com/juju/ratelimit v1.0.1 h1:+7AIFJVQ0EQgq/K9+0Krm7m530Du7tIz0METWzN0RgY=
github.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk=
github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/kisielk/errcheck v1.1.0 h1:ZqfnKyx9KGpRcW04j5nnPDgRgoXUeLh2YFBeFzphcA0=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v0.0.0-20161130080628-0de1eaf82fa3/go.mod h1:jxZFDH7ILpTPQTk+E2s+z4CUas9lVNjIuKR4c5/zKgM=
github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.4.1 h1:8VMb5+0wMgdBykOV96DwNwKFQ+WTI4pzYURP99CcB9E=
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid v1.2.0 h1:NMpwD2G9JSFOE1/TJjGSo5zG7Yb2bTe7eq1jH+irmeE=
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
@@ -465,13 +550,19 @@ github.com/kr/pty v1.1.8 h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/letsencrypt/pkcs11key v2.0.1-0.20170608213348-396559074696+incompatible h1:GfzE+uq7odDW7nOmp1QWuilLEK7kJf8i84XcIfk3mKA=
github.com/letsencrypt/pkcs11key v2.0.1-0.20170608213348-396559074696+incompatible/go.mod h1:iGYXKqDXt0cpBthCHdr9ZdsQwyGlYFh/+8xa4WzIQ34=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743 h1:143Bb8f8DuGWck/xpNUOckBVYfFbBTnLevfRZ1aVVqo=
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
github.com/lightstep/lightstep-tracer-go v0.18.1 h1:vi1F1IQ8N7hNWytK9DpJsUfQhGuNSc19z330K6vl4zk=
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e h1:9MlwzLdW7QSDrhDjFlsEYmxpFyIoXmYRon3dt0io31k=
github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
github.com/lunixbochs/vtclean v1.0.0 h1:xu2sLAri4lGiovBDQKxl5mrXyESr3gUr5m5SM5+LVb8=
@@ -492,22 +583,24 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA=
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/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/goveralls v0.0.2 h1:7eJB6EqsPhRVxvwEXGnqdO2sJI0PTsrWoTMXEk9/OQc=
github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
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/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
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=
github.com/mitchellh/cli v1.0.0 h1:iGBIsUe3+HZ/AD/Vd7DErOt5sU9fa8Uj7A2s1aggv1Y=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
@@ -515,9 +608,13 @@ github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk=
github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b h1:9+ke9YJ9KGWw5ANXK6ozjoK47uI3uNbXv4YVINBnGm8=
github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk=
github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/gox v0.4.0 h1:lfGJxY7ToLJQjHHwi0EX6uYBdK78egf954SQl13PQJc=
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
@@ -531,17 +628,26 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/mozilla/tls-observatory v0.0.0-20180409132520-8791a200eb40/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=
github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd h1:Av0AX0PnAlPZ3AY2rQUobGFaZfE4KHVRdKWIEPvsCWY=
github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=
github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474 h1:oKIteTqeSpenyTrOVj5zkiyCaflLa8B+CD0324otT+o=
github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223 h1:F9x/1yl3T2AeKLr2AMdilSD8+f9bvMnNN8VS5iDtovc=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
github.com/nats-io/jwt v0.3.2 h1:+RB5hMpXUUA2dfxuhBTEkMOrYmM+gKIZYS1KjSostMI=
github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
github.com/nats-io/nats-server/v2 v2.1.2 h1:i2Ly0B+1+rzNZHHWtD4ZwKi+OU5l+uQo1iDHZ2PmiIc=
github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
github.com/nats-io/nats.go v1.9.1 h1:ik3HbLhZ0YABLto7iX80pZLPw/6dx3T+++MZJwLnMrQ=
github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
github.com/nats-io/nkeys v0.1.3 h1:6JrEfig+HzTH85yxzhSVbjHRJv9cn0p6n3IngIcM5/k=
github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/nbutton23/zxcvbn-go v0.0.0-20160627004424-a22cb81b2ecd/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
github.com/nbutton23/zxcvbn-go v0.0.0-20171102151520-eafdab6b0663/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
@@ -549,9 +655,13 @@ github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d h1:AREM5mwr4u1
github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
github.com/newrelic/go-agent v2.15.0+incompatible h1:IB0Fy+dClpBq9aEoIrLyQXzU34JyI1xVTanPLB/+jvU=
github.com/newrelic/go-agent v2.15.0+incompatible/go.mod h1:a8Fv1b/fYhFSReoTU6HDkTYIMZeSVNffmoS726Y0LzQ=
github.com/ngdinhtoan/glide-cleanup v0.2.0 h1:kN4sV+0tp2F1BvwU+5SfNRMDndRmvIfnI3kZ7B8Yv4Y=
github.com/ngdinhtoan/glide-cleanup v0.2.0/go.mod h1:UQzsmiDOb8YV3nOsCxK/c9zPpCZVNoHScRE3EO9pVMM=
github.com/oklog/oklog v0.3.2 h1:wVfs8F+in6nTBMkA7CbRw+zZMIB7nNM825cM1wuzoTk=
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.1 h1:b3iUnf1v+ppJiOfNX4yxxqfWKMQPZR5yoh8urCTFX88=
@@ -566,31 +676,44 @@ github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34=
github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492 h1:lM6RxxfUMrYL/f8bWEUqdXrANWtrL7Nndbm9iFN0DlU=
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
github.com/opentracing/basictracer-go v1.0.0 h1:YyUAhaEfjoWXclZVJ9sGoNct7j4TVk7lZWlQw5UXuoo=
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5 h1:ZCnq+JUrvXcDVhX/xRolRBZifmabN1HcS1wrPSvxhrU=
github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
github.com/openzipkin/zipkin-go v0.2.2 h1:nY8Hti+WKaP0cRsSeQ026wU03QsM762XBeCXBb9NAWI=
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
github.com/pact-foundation/pact-go v1.0.4 h1:OYkFijGHoZAYbOIb1LWXrwKQbMMRUv1oQ89blD2Mh2Q=
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.1.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/performancecopilot/speed v3.0.0+incompatible h1:2WnRzIquHa5QxaJKShDkLM+sc0JPuwhXzK8OYOyt3Vg=
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.2.1 h1:F++O52m40owAmADcojzM+9gyjmMOY/T4oYJkgFDH8RE=
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1 h1:ccV59UEOTzVDnDUEFdT95ZzHVZ+5+158q8+SJb2QV5w=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/pquerna/otp v1.0.0 h1:TBZrpfnzVbgmpYhiYBK+bJ4Ig0+ye+GGNMe2pTrvxCo=
github.com/pquerna/otp v1.0.0/go.mod h1:Zad1CMQfSQZI5KLpahDiSUX4tMMREnXw98IvL1nhgMk=
@@ -619,12 +742,18 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c h1:JoUA0uz9U0FVFq5p4LjEq4C0VgQ0El320s3Ms0V4eww=
github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af h1:gu+uRPtBe88sKxUCEXRoeCvVG90TJmwhiqRpvdhQFng=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI=
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
@@ -632,17 +761,24 @@ github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNue
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f h1:UFr9zpz4xgTnIE5yIMtWAMngCdZ9p/+q6lTbgelo80M=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735 h1:7YvPJVmEeFHR1Tj9sZEYsmarJEQfMVYpd/Vyy/A8dqE=
github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
github.com/samfoo/ansi v0.0.0-20160124022901-b6bd2ded7189 h1:CmSpbxmewNQbzqztaY0bke1qzHhyNyC29wYgh17Gxfo=
github.com/samfoo/ansi v0.0.0-20160124022901-b6bd2ded7189/go.mod h1:UUwuHEJ9zkkPDxspIHOa59PUeSkGFljESGzbxntLmIg=
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da h1:p3Vo3i64TCLY7gIfzeQaUJ+kppEO5WQG3cL8iE8tGHU=
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/securego/gosec v0.0.0-20200103095621-79fbf3af8d83 h1:AtnWoOvTioyDXFvu96MWEeE8qj4COSQnJogzLy/u41A=
github.com/securego/gosec v0.0.0-20200103095621-79fbf3af8d83/go.mod h1:vvbZ2Ae7AzSq3/kywjUDxSNq2SJ27RxCz2un0H3ePqE=
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shirou/gopsutil v0.0.0-20180427012116-c95755e4bcd7/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada h1:WokF3GuxBeL+n4Lk4Fa8v9mbdjlrl7bHuneF4N1bk2I=
github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc=
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 h1:udFKJ0aHUL60LboW/A+DfgoHVedieIzIXE8uylPue0U=
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e h1:MZM7FHLqUHYI0Y/mQAt3d2aYa0SiNms/hFqC9qJYolM=
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
@@ -677,6 +813,7 @@ github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIK
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/sony/gobreaker v0.4.1 h1:oMnRNZXX5j85zso6xCPRNPtmAycat+WcoKbklScLDgQ=
github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
github.com/sourcegraph/go-diff v0.5.1 h1:gO6i5zugwzo1RVTvgvfwCOSVegNuvnNi6bAD1QCmkHs=
github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE=
@@ -707,6 +844,9 @@ github.com/spf13/viper v1.6.1 h1:VPZzIkznI1YhVMRi6vNFLHSwhnhReBfgTxIPccpfdZk=
github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271 h1:WhxRHzgeVGETMlmVfqhRn8RIeeNoPr2Czh33I4Zdccw=
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a h1:AhmOdSHeswKHBjhsLs/7+1voOxT+LLrSk/Nxvk35fug=
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
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=
@@ -721,6 +861,7 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
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/thales-e-security/pool v0.0.2 h1:RAPs4q2EbWsTit6tpzuvTFlgFRJ3S8Evf5gtvVDbmPg=
github.com/thales-e-security/pool v0.0.2/go.mod h1:qtpMm2+thHtqhLzTwgDBj/OuNnMpupY8mv0Phz0gjhU=
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=
@@ -728,10 +869,13 @@ github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiff
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
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 h1:fb190+cK2Xz/dvi9Hv8eCYJYvIGUTN2/KLq1pT6CjEc=
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4=
github.com/tommy-muehle/go-mnd v1.3.1-0.20200224220436-e6f9a994e8fa h1:RC4maTWLKKwb7p1cnoygsbKIgNlJqSYBeAFON3Ar8As=
github.com/tommy-muehle/go-mnd v1.3.1-0.20200224220436-e6f9a994e8fa/go.mod h1:dSUh0FtTP8VhvkL1S+gUR1OKd9ZnSaozuI6r3m6wOig=
github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8 h1:3SVOIvH7Ae1KRYyQWRjXWJEA9sS/c/pjvH++55Gr648=
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=
@@ -745,26 +889,36 @@ github.com/urfave/cli v1.22.4 h1:u7tSpNPPswAFymm8IehJhy4uJMlUuU/GmqSkvJ1InXA=
github.com/urfave/cli v1.22.4/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 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.2.0 h1:dzZJf2IuMiclVjdw0kkT+f9u4YdrapbNyGAN47E/qnk=
github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s=
github.com/valyala/quicktemplate v1.1.1/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4=
github.com/valyala/quicktemplate v1.2.0 h1:BaO1nHTkspYzmAjPXj0QiDJxai96tlcZyKcI9dyEGvM=
github.com/valyala/quicktemplate v1.2.0/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a h1:0R4NLDRDZX6JcmhJgXi5E4b8Wg84ihbmUKp/GvSPEzc=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
github.com/weppos/publicsuffix-go v0.4.0 h1:YSnfg3V65LcCFKtIGKGoBhkyKolEd0hlipcXaOjdnQw=
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 h1:ESFSdwYZvkeru3RtdrYueztKhOBCSAAzS4Gf+k0tEow=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1 h1:ruQGxdhGHe7FWOJPT0mKs5+pD2Xs1Bm/kdGlHO04FmM=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/zmap/rc2 v0.0.0-20131011165748-24b9757f5521/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE=
github.com/zmap/rc2 v0.0.0-20190804163417-abaa70531248 h1:Nzukz5fNOBIHOsnP+6I79kPx3QhLv8nBy2mfFhBRq30=
github.com/zmap/rc2 v0.0.0-20190804163417-abaa70531248/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE=
github.com/zmap/zcertificate v0.0.0-20180516150559-0e3d58b1bac4/go.mod h1:5iU54tB79AMBcySS0R2XIyZBAVmeHranShAFELYx7is=
github.com/zmap/zcertificate v0.0.0-20190521191901-30e388164f71 h1:hxHelFG6LEcCsUyu6oKo4P7ZkmzLLeQhOZlVtaUymBk=
github.com/zmap/zcertificate v0.0.0-20190521191901-30e388164f71/go.mod h1:gIZi1KPgkZNUQzPZXsZrNnUnxy05nTc0+tmlqvIkhRw=
github.com/zmap/zcrypto v0.0.0-20190329181646-dff83107394d h1:EoQIHS1co8tkbljRLMADWiRAWLcKI02M/ZtPrAUxjHc=
github.com/zmap/zcrypto v0.0.0-20190329181646-dff83107394d/go.mod h1:ix3q2kpLy0ibAuFXlr7qOhPKwFRRSjuynGuTR8EUPCk=
github.com/zmap/zlint v0.0.0-20190516161541-9047d02cf65a h1:174pnZ4WOF6mGuOJy7Qm6V3cmWn61CfhAWMxvPhqwmc=
github.com/zmap/zlint v0.0.0-20190516161541-9047d02cf65a/go.mod h1:xwLbce0UzBXp44sIAL1cii+hoK8j4AxRKlymZA2AIcY=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
@@ -783,13 +937,14 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.step.sm/cli-utils v0.2.0 h1:hpVu9+6dpv/7/Bd8nGJFc3V+gQ+TciSJRTu9TavDUQ4=
go.step.sm/cli-utils v0.2.0/go.mod h1:+t4qCp5NO+080DdGkJxEh3xL5S4TcYC2JTPLMM72b6Y=
go.step.sm/crypto v0.6.1/go.mod h1:AKS4yMZVZD4EGjpSkY4eibuMenrvKCscb+BpWMet8c0=
go.step.sm/cli-utils v0.4.1 h1:QztRUhGYjOPM1I2Nmi7V6XejQyVtcESmo+sbegxvX7Q=
go.step.sm/cli-utils v0.4.1/go.mod h1:hWYVOSlw8W9Pd+BwIbs/aftVVMRms3EG7Q2qLRwc0WA=
go.step.sm/crypto v0.8.3 h1:TO/OPlaUrYXhs8srGEFNyL6OWVQvRmEPCUONNnQUuEM=
go.step.sm/crypto v0.8.3/go.mod h1:+CYG05Mek1YDqi5WK0ERc6cOpKly2i/a5aZmU1sfGj0=
go.step.sm/crypto v0.9.0 h1:q2AllTSnVj4NRtyEPkGW2ohArLmbGbe6ZAL/VIOKDzA=
go.step.sm/crypto v0.9.0/go.mod h1:+CYG05Mek1YDqi5WK0ERc6cOpKly2i/a5aZmU1sfGj0=
go.step.sm/linkedca v0.0.0-20210611183751-27424aae8d25 h1:ncJqviWswJT19IdnfOYQGKG1zL7IDy4lAJz1PuM3fgw=
go.step.sm/linkedca v0.0.0-20210611183751-27424aae8d25/go.mod h1:5uTRjozEGSPAZal9xJqlaD38cvJcLe3o1VAFVjqcORo=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY=
@@ -825,8 +980,10 @@ golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -836,11 +993,13 @@ golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHl
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
@@ -848,10 +1007,6 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20170726083632-f5079bd7f6f7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20170915142106-8351a756f30f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -923,10 +1078,8 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20170728174421-0f826bdd13b5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20171026204733-164713f0dfce/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -977,16 +1130,6 @@ golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 h1:RqytpXGR1iVNX7psjB3ff8y7sNFinVFvkx1c8SjBkio=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210503060354-a79de5458b56 h1:b8jxX3zqjpqb2LklXPzKSGJhzyxCOZSz8ncv8Nv+y7w=
golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY=
@@ -996,10 +1139,6 @@ 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/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
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=
@@ -1098,13 +1237,8 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
google.golang.org/api v0.47.0 h1:sQLWZQvP6jPGIP4JGPkJu4zHswrv81iobiyszr3b/0I=
google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=
google.golang.org/api v0.33.0 h1:+gL0XvACeMIvpwLZ5rQZzLn5cwOsgg8dIcfJ2SYfBVw=
google.golang.org/api v0.33.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -1158,9 +1292,9 @@ google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQ
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d h1:KzwjikDymrEmYYbdyfievTwjEeGlu+OM6oiKBkF3Jfg=
google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/grpc v1.32.0 h1:zWTV+LMdc3kaiJMSTOFz2UgSBgx8RNQoTGiZu3fR9S0=
google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -1174,7 +1308,9 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/airbrake/gobrake.v2 v2.0.9 h1:7z2uVWwn7oVeeugY1DtlPAy5H+KYgB1KeKTnqjNatLo=
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -1183,18 +1319,23 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
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 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gcfg.v1 v1.2.3 h1:m8OOJ4ccYHnx2f4gQwpno8nAX5OGOh7RLaaz0pj3Ogs=
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 h1:OAj3g0cR6Dx/R07QgQe8wkA9RNjB2u4i700xBkIT4e0=
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w=
gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
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=
@@ -1222,12 +1363,17 @@ mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jC
mvdan.cc/unparam v0.0.0-20190209190245-fbb59629db34/go.mod h1:H6SUd1XjIs+qQCyskXg5OFSrilMRUkD8ePJpHKDPaeY=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f h1:Cq7MalBHYACRd6EesksG1Q8EoIAKOsiZviGKbOLIej4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
software.sslmate.com/src/go-pkcs12 v0.0.0-20201103104416-57fc603b7f52 h1:yJEpdXGdVrQ+4noW8axHuvS7jFLwDJkJM2I884HoXjA=
software.sslmate.com/src/go-pkcs12 v0.0.0-20201103104416-57fc603b7f52/go.mod h1:/xvNRWUqm0+/ZMiF4EX00vrSCMsE4/NHb+Pt3freEeQ=
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0 h1:ucqkfpjg9WzSUubAO62csmucvxl4/JeW3F4I4909XkM=
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4 h1:JPJh2pk3+X4lXAkZIk2RuE/7/FoK9maXw+TNPJhVS/c=
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=

View File

@@ -1,15 +1,23 @@
package cautils
import (
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"net/http"
"os"
"time"
"github.com/pkg/errors"
"github.com/smallstep/certificates/api"
"github.com/smallstep/certificates/authority/provisioner"
"github.com/smallstep/certificates/ca"
"github.com/smallstep/certificates/pki"
"github.com/smallstep/cli/crypto/keys"
"github.com/smallstep/cli/crypto/pemutil"
"github.com/smallstep/cli/errs"
"github.com/smallstep/cli/flags"
"github.com/smallstep/cli/ui"
"github.com/urfave/cli"
)
@@ -58,3 +66,110 @@ func NewClient(ctx *cli.Context, opts ...ca.ClientOption) (CaClient, error) {
opts = append([]ca.ClientOption{ca.WithRootFile(root)}, opts...)
return ca.NewClient(caURL, opts...)
}
// NewAdminClient returns a client for the mgmt API of the online CA.
func NewAdminClient(ctx *cli.Context, opts ...ca.ClientOption) (*ca.AdminClient, error) {
caURL, err := flags.ParseCaURLIfExists(ctx)
if err != nil {
return nil, err
}
if len(caURL) == 0 {
return nil, errs.RequiredFlag(ctx, "ca-url")
}
root := ctx.String("root")
if len(root) == 0 {
root = pki.GetRootCAPath()
if _, err := os.Stat(root); err != nil {
return nil, errs.RequiredFlag(ctx, "root")
}
}
var (
adminCertFile = ctx.String("admin-cert")
adminKeyFile = ctx.String("admin-key")
adminCert []*x509.Certificate
adminKey interface{}
)
if len(adminCertFile) > 0 || len(adminKeyFile) > 0 {
if len(adminCertFile) == 0 {
return nil, errs.RequiredWithFlag(ctx, "admin-key", "admin-cert")
}
if len(adminKeyFile) == 0 {
return nil, errs.RequiredWithFlag(ctx, "admin-cert", "admin-key")
}
adminCert, err = pemutil.ReadCertificateBundle(adminCertFile)
if err != nil {
return nil, errors.Wrap(err, "error reading admin certificate")
}
adminKey, err = pemutil.Read(adminKeyFile)
if err != nil {
return nil, errors.Wrap(err, "error reading admin key")
}
} else {
// Generate a new admin cert/key in memory.
client, err := ca.NewClient(caURL, ca.WithRootFile(root))
if err != nil {
return nil, err
}
subject := ctx.String("admin-subject")
if subject == "" {
subject, err = ui.Prompt("Please enter the name of the admin executing this command", ui.WithValidateNotEmpty())
if err != nil {
return nil, err
}
}
tok, err := NewTokenFlow(ctx, SignType, subject, []string{subject}, caURL, root, time.Time{}, time.Time{}, provisioner.TimeDuration{}, provisioner.TimeDuration{})
if err != nil {
return nil, err
}
dnsNames, ips, emails, uris := splitSANs([]string{subject})
template := &x509.CertificateRequest{
Subject: pkix.Name{
CommonName: subject,
},
DNSNames: dnsNames,
IPAddresses: ips,
EmailAddresses: emails,
URIs: uris,
}
adminKey, err = keys.GenerateKey("EC", "P-256", 0)
if err != nil {
return nil, err
}
csr, err := x509.CreateCertificateRequest(rand.Reader, template, adminKey)
if err != nil {
return nil, errors.Wrap(err, "error creating admin certificate request")
}
cr, err := x509.ParseCertificateRequest(csr)
if err != nil {
return nil, errors.Wrap(err, "error parsing admin certificate request")
}
if err := cr.CheckSignature(); err != nil {
return nil, errors.Wrap(err, "error signing admin certificate request")
}
signRequest := &api.SignRequest{
CsrPEM: api.CertificateRequest{CertificateRequest: cr},
OTT: tok,
}
signResponse, err := client.Sign(signRequest)
if err != nil {
return nil, err
}
if signResponse.CertChainPEM == nil || len(signResponse.CertChainPEM) == 0 {
signResponse.CertChainPEM = []api.Certificate{signResponse.ServerPEM, signResponse.CaPEM}
}
adminCert = make([]*x509.Certificate, len(signResponse.CertChainPEM))
for i, c := range signResponse.CertChainPEM {
adminCert[i] = c.Certificate
}
}
// Create online client
opts = append([]ca.ClientOption{ca.WithRootFile(root),
ca.WithAdminX5C(adminCert, adminKey, ctx.String("password-file"))},
opts...)
return ca.NewAdminClient(caURL, opts...)
}

View File

@@ -13,6 +13,7 @@ import (
"github.com/pkg/errors"
"github.com/smallstep/certificates/api"
"github.com/smallstep/certificates/authority"
"github.com/smallstep/certificates/authority/config"
"github.com/smallstep/certificates/authority/provisioner"
"github.com/smallstep/cli/crypto/pemutil"
"github.com/smallstep/cli/crypto/x509util"
@@ -25,7 +26,7 @@ import (
// used to sign certificates without an online CA.
type OfflineCA struct {
authority *authority.Authority
config authority.Config
config config.Config
configFile string
}
@@ -45,23 +46,23 @@ func NewOfflineCA(configFile string) (*OfflineCA, error) {
return nil, err
}
var config authority.Config
if err = json.Unmarshal(b, &config); err != nil {
var cfg config.Config
if err = json.Unmarshal(b, &cfg); err != nil {
return nil, errors.Wrapf(err, "error reading %s", configFile)
}
if config.AuthorityConfig == nil || len(config.AuthorityConfig.Provisioners) == 0 {
if cfg.AuthorityConfig == nil || len(cfg.AuthorityConfig.Provisioners) == 0 {
return nil, errors.Errorf("error parsing %s: no provisioners found", configFile)
}
auth, err := authority.New(&config)
auth, err := authority.New(&cfg)
if err != nil {
return nil, err
}
offlineInstance = &OfflineCA{
authority: auth,
config: config,
config: cfg,
configFile: configFile,
}
return offlineInstance, nil

View File

@@ -95,10 +95,7 @@ func (e *apiError) Error() string {
func readJSON(r io.ReadCloser, v interface{}) error {
defer r.Close()
if err := json.NewDecoder(r).Decode(v); err != nil {
return err
}
return nil
return json.NewDecoder(r).Decode(v)
}
func readError(r io.ReadCloser) error {

View File

@@ -297,6 +297,16 @@ func provisionerPrompt(ctx *cli.Context, provisioners provisioner.List) (provisi
}
}
// Filter by admin-issuer (provisioner name)
if issuer := ctx.String("admin-provisioner"); len(issuer) != 0 {
provisioners = provisionerFilter(provisioners, func(p provisioner.Interface) bool {
return p.GetName() == issuer
})
if len(provisioners) == 0 {
return nil, errs.InvalidFlagValue(ctx, "admin-issuer", issuer, "")
}
}
// Select provisioner
var items []*provisionersSelect
for _, prov := range provisioners {

View File

@@ -175,7 +175,7 @@ func generateX5CToken(ctx *cli.Context, p *provisioner.X5C, tokType int, tokAttr
return "", err
}
tokenGen := NewTokenGenerator(jwk.KeyID, p.Name,
fmt.Sprintf("%s#%s", tokAttrs.audience, p.GetID()), tokAttrs.root,
fmt.Sprintf("%s#%s", tokAttrs.audience, p.GetIDForToken()), tokAttrs.root,
tokAttrs.notBefore, tokAttrs.notAfter, jwk)
switch tokType {
case SignType:
@@ -213,7 +213,7 @@ func generateSSHPOPToken(ctx *cli.Context, p *provisioner.SSHPOP, tokType int, t
return "", err
}
tokenGen := NewTokenGenerator(jwk.KeyID, p.Name,
fmt.Sprintf("%s#%s", tokAttrs.audience, p.GetID()), tokAttrs.root,
fmt.Sprintf("%s#%s", tokAttrs.audience, p.GetIDForToken()), tokAttrs.root,
tokAttrs.notBefore, tokAttrs.notAfter, jwk)
switch tokType {
case SSHRevokeType: