forked from TrueCloudLab/certificates
Add endpoint id for the RA certificate
In a linked RA mode, send an endpoint id to group the server certificates.
This commit is contained in:
parent
eb091aec54
commit
5df1694250
12 changed files with 113 additions and 42 deletions
|
@ -273,11 +273,13 @@ func (c *linkedCaClient) GetCertificateData(serial string) (*db.CertificateData,
|
||||||
func (c *linkedCaClient) StoreCertificateChain(p provisioner.Interface, fullchain ...*x509.Certificate) error {
|
func (c *linkedCaClient) StoreCertificateChain(p provisioner.Interface, fullchain ...*x509.Certificate) error {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
raProvisioner, endpointID := createRegistrationAuthorityProvisioner(p)
|
||||||
_, err := c.client.PostCertificate(ctx, &linkedca.CertificateRequest{
|
_, err := c.client.PostCertificate(ctx, &linkedca.CertificateRequest{
|
||||||
PemCertificate: serializeCertificateChain(fullchain[0]),
|
PemCertificate: serializeCertificateChain(fullchain[0]),
|
||||||
PemCertificateChain: serializeCertificateChain(fullchain[1:]...),
|
PemCertificateChain: serializeCertificateChain(fullchain[1:]...),
|
||||||
Provisioner: createProvisionerIdentity(p),
|
Provisioner: createProvisionerIdentity(p),
|
||||||
RaProvisioner: createRegistrationAuthorityProvisioner(p),
|
RaProvisioner: raProvisioner,
|
||||||
|
EndpointId: endpointID,
|
||||||
})
|
})
|
||||||
return errors.Wrap(err, "error posting certificate")
|
return errors.Wrap(err, "error posting certificate")
|
||||||
}
|
}
|
||||||
|
@ -397,7 +399,7 @@ type raProvisioner interface {
|
||||||
RAInfo() *provisioner.RAInfo
|
RAInfo() *provisioner.RAInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func createRegistrationAuthorityProvisioner(p provisioner.Interface) *linkedca.RegistrationAuthorityProvisioner {
|
func createRegistrationAuthorityProvisioner(p provisioner.Interface) (*linkedca.RegistrationAuthorityProvisioner, string) {
|
||||||
if rap, ok := p.(raProvisioner); ok {
|
if rap, ok := p.(raProvisioner); ok {
|
||||||
info := rap.RAInfo()
|
info := rap.RAInfo()
|
||||||
typ := linkedca.Provisioner_Type_value[strings.ToUpper(info.ProvisionerType)]
|
typ := linkedca.Provisioner_Type_value[strings.ToUpper(info.ProvisionerType)]
|
||||||
|
@ -408,9 +410,9 @@ func createRegistrationAuthorityProvisioner(p provisioner.Interface) *linkedca.R
|
||||||
Type: linkedca.Provisioner_Type(typ),
|
Type: linkedca.Provisioner_Type(typ),
|
||||||
Name: info.ProvisionerName,
|
Name: info.ProvisionerName,
|
||||||
},
|
},
|
||||||
|
}, info.EndpointID
|
||||||
}
|
}
|
||||||
}
|
return nil, ""
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func serializeCertificate(crt *x509.Certificate) string {
|
func serializeCertificate(crt *x509.Certificate) string {
|
||||||
|
|
|
@ -343,10 +343,11 @@ type Permissions struct {
|
||||||
// RAInfo is the information about a provisioner present in RA tokens generated
|
// RAInfo is the information about a provisioner present in RA tokens generated
|
||||||
// by StepCAS.
|
// by StepCAS.
|
||||||
type RAInfo struct {
|
type RAInfo struct {
|
||||||
AuthorityID string `json:"authorityId"`
|
AuthorityID string `json:"authorityId,omitempty"`
|
||||||
ProvisionerID string `json:"provisionerId"`
|
EndpointID string `json:"endpointId,omitempty"`
|
||||||
ProvisionerType string `json:"provisionerType"`
|
ProvisionerID string `json:"provisionerId,omitempty"`
|
||||||
ProvisionerName string `json:"provisionerName"`
|
ProvisionerType string `json:"provisionerType,omitempty"`
|
||||||
|
ProvisionerName string `json:"provisionerName,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// raProvisioner wraps a provisioner with RA data.
|
// raProvisioner wraps a provisioner with RA data.
|
||||||
|
|
|
@ -619,6 +619,7 @@ func (a *Authority) GetTLSCertificate() (*tls.Certificate, error) {
|
||||||
CSR: cr,
|
CSR: cr,
|
||||||
Lifetime: 24 * time.Hour,
|
Lifetime: 24 * time.Hour,
|
||||||
Backdate: 1 * time.Minute,
|
Backdate: 1 * time.Minute,
|
||||||
|
IsServerCert: true,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fatal(err)
|
return fatal(err)
|
||||||
|
|
|
@ -58,6 +58,7 @@ type CreateCertificateRequest struct {
|
||||||
Backdate time.Duration
|
Backdate time.Duration
|
||||||
RequestID string
|
RequestID string
|
||||||
Provisioner *ProvisionerInfo
|
Provisioner *ProvisionerInfo
|
||||||
|
IsServerCert bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProvisionerInfo contains information of the provisioner used to authorize a
|
// ProvisionerInfo contains information of the provisioner used to authorize a
|
||||||
|
|
|
@ -5,16 +5,29 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/smallstep/certificates/ca"
|
"github.com/smallstep/certificates/ca"
|
||||||
"github.com/smallstep/certificates/cas/apiv1"
|
"github.com/smallstep/certificates/cas/apiv1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// raAuthorityNS is a custom namespace used to generate endpoint ids based on
|
||||||
|
// the authority id.
|
||||||
|
var raAuthorityNS = uuid.MustParse("d6f14c1f-2f92-47bf-a04f-7b2c11382edd")
|
||||||
|
|
||||||
|
// newServerEndpointID returns a uuid v5 using raAuthorityNS as the namespace.
|
||||||
|
// The return uuid will be used as the server endpoint id, it will be unique per
|
||||||
|
// authority.
|
||||||
|
func newServerEndpointID(data string) uuid.UUID {
|
||||||
|
return uuid.NewSHA1(raAuthorityNS, []byte(data))
|
||||||
|
}
|
||||||
|
|
||||||
type raInfo struct {
|
type raInfo struct {
|
||||||
AuthorityID string `json:"authorityId,omitempty"`
|
AuthorityID string `json:"authorityId,omitempty"`
|
||||||
ProvisionerID string `json:"provisionerId"`
|
EndpointID string `json:"endpointId,omitempty"`
|
||||||
ProvisionerType string `json:"provisionerType"`
|
ProvisionerID string `json:"provisionerId,omitempty"`
|
||||||
ProvisionerName string `json:"provisionerName"`
|
ProvisionerType string `json:"provisionerType,omitempty"`
|
||||||
|
ProvisionerName string `json:"provisionerName,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type stepIssuer interface {
|
type stepIssuer interface {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
"github.com/smallstep/certificates/ca"
|
"github.com/smallstep/certificates/ca"
|
||||||
"github.com/smallstep/certificates/cas/apiv1"
|
"github.com/smallstep/certificates/cas/apiv1"
|
||||||
"go.step.sm/crypto/jose"
|
"go.step.sm/crypto/jose"
|
||||||
|
@ -35,6 +36,42 @@ func (s *mockErrSigner) Options() jose.SignerOptions {
|
||||||
return jose.SignerOptions{}
|
return jose.SignerOptions{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_newServerEndpointID(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want []byte
|
||||||
|
}{
|
||||||
|
{"ok", args{"foo"}, []byte{
|
||||||
|
0x8f, 0x63, 0x69, 0x20, 0x8a, 0x7a, 0x57, 0x0c, 0xbe, 0x4c, 0x46, 0x66, 0x77, 0xf8, 0x54, 0xe7,
|
||||||
|
}},
|
||||||
|
{"ok uuid", args{"e4fa6d2d-fa9c-4fdc-913e-7484cc9516e4"}, []byte{
|
||||||
|
0x8d, 0x8d, 0x7f, 0x04, 0x73, 0xd4, 0x5f, 0x2f, 0xa8, 0xe1, 0x28, 0x9a, 0xd1, 0xa8, 0xcf, 0x7e,
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
var want uuid.UUID
|
||||||
|
copy(want[:], tt.want)
|
||||||
|
got := newServerEndpointID(tt.args.name)
|
||||||
|
if !reflect.DeepEqual(got, want) {
|
||||||
|
t.Errorf("newServerEndpointID() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
// Check version
|
||||||
|
if v := (got[6] & 0xf0) >> 4; v != 5 {
|
||||||
|
t.Errorf("newServerEndpointID() version = %d, want 5", v)
|
||||||
|
}
|
||||||
|
// Check variant
|
||||||
|
if v := (got[8] & 0x80) >> 6; v != 2 {
|
||||||
|
t.Errorf("newServerEndpointID() variant = %d, want 2", v)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func Test_newStepIssuer(t *testing.T) {
|
func Test_newStepIssuer(t *testing.T) {
|
||||||
caURL, client := testCAHelper(t)
|
caURL, client := testCAHelper(t)
|
||||||
signer, err := newJWKSignerFromEncryptedKey(testKeyID, testEncryptedJWKKey, testPassword)
|
signer, err := newJWKSignerFromEncryptedKey(testKeyID, testEncryptedJWKKey, testPassword)
|
||||||
|
|
|
@ -48,6 +48,9 @@ func Test_jwkIssuer_SignToken(t *testing.T) {
|
||||||
{"ok ra", fields{caURL, "ra@doe.org", signer}, args{"doe", []string{"doe.org"}, &raInfo{
|
{"ok ra", fields{caURL, "ra@doe.org", signer}, args{"doe", []string{"doe.org"}, &raInfo{
|
||||||
AuthorityID: "authority-id", ProvisionerID: "provisioner-id", ProvisionerType: "provisioner-type",
|
AuthorityID: "authority-id", ProvisionerID: "provisioner-id", ProvisionerType: "provisioner-type",
|
||||||
}}, false},
|
}}, false},
|
||||||
|
{"ok ra endpoint id", fields{caURL, "ra@doe.org", signer}, args{"doe", []string{"doe.org"}, &raInfo{
|
||||||
|
AuthorityID: "authority-id", EndpointID: "endpoint-id",
|
||||||
|
}}, false},
|
||||||
{"fail", fields{caURL, "ra@doe.org", &mockErrSigner{}}, args{"doe", []string{"doe.org"}, nil}, true},
|
{"fail", fields{caURL, "ra@doe.org", &mockErrSigner{}}, args{"doe", []string{"doe.org"}, nil}, true},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
|
|
@ -75,14 +75,16 @@ func (s *StepCAS) CreateCertificate(req *apiv1.CreateCertificateRequest) (*apiv1
|
||||||
return nil, errors.New("createCertificateRequest `lifetime` cannot be 0")
|
return nil, errors.New("createCertificateRequest `lifetime` cannot be 0")
|
||||||
}
|
}
|
||||||
|
|
||||||
var info *raInfo
|
info := &raInfo{
|
||||||
if p := req.Provisioner; p != nil {
|
|
||||||
info = &raInfo{
|
|
||||||
AuthorityID: s.authorityID,
|
AuthorityID: s.authorityID,
|
||||||
ProvisionerID: p.ID,
|
|
||||||
ProvisionerType: p.Type,
|
|
||||||
ProvisionerName: p.Name,
|
|
||||||
}
|
}
|
||||||
|
if req.IsServerCert {
|
||||||
|
info.EndpointID = newServerEndpointID(s.authorityID).String()
|
||||||
|
}
|
||||||
|
if p := req.Provisioner; p != nil {
|
||||||
|
info.ProvisionerID = p.ID
|
||||||
|
info.ProvisionerType = p.Type
|
||||||
|
info.ProvisionerName = p.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
cert, chain, err := s.createCertificate(req.CSR, req.Lifetime, info)
|
cert, chain, err := s.createCertificate(req.CSR, req.Lifetime, info)
|
||||||
|
|
|
@ -672,6 +672,14 @@ func TestStepCAS_CreateCertificate(t *testing.T) {
|
||||||
Certificate: testCrt,
|
Certificate: testCrt,
|
||||||
CertificateChain: []*x509.Certificate{testIssCrt},
|
CertificateChain: []*x509.Certificate{testIssCrt},
|
||||||
}, false},
|
}, false},
|
||||||
|
{"ok with server cert", fields{jwk, client, testRootFingerprint}, args{&apiv1.CreateCertificateRequest{
|
||||||
|
CSR: testCR,
|
||||||
|
Lifetime: time.Hour,
|
||||||
|
IsServerCert: true,
|
||||||
|
}}, &apiv1.CreateCertificateResponse{
|
||||||
|
Certificate: testCrt,
|
||||||
|
CertificateChain: []*x509.Certificate{testIssCrt},
|
||||||
|
}, false},
|
||||||
{"fail CSR", fields{x5c, client, testRootFingerprint}, args{&apiv1.CreateCertificateRequest{
|
{"fail CSR", fields{x5c, client, testRootFingerprint}, args{&apiv1.CreateCertificateRequest{
|
||||||
CSR: nil,
|
CSR: nil,
|
||||||
Lifetime: time.Hour,
|
Lifetime: time.Hour,
|
||||||
|
|
|
@ -72,6 +72,9 @@ func Test_x5cIssuer_SignToken(t *testing.T) {
|
||||||
{"ok ra", fields{caURL, testX5CPath, testX5CKeyPath, "X5C"}, args{"doe", []string{"doe.org"}, &raInfo{
|
{"ok ra", fields{caURL, testX5CPath, testX5CKeyPath, "X5C"}, args{"doe", []string{"doe.org"}, &raInfo{
|
||||||
AuthorityID: "authority-id", ProvisionerID: "provisioner-id", ProvisionerType: "provisioner-type",
|
AuthorityID: "authority-id", ProvisionerID: "provisioner-id", ProvisionerType: "provisioner-type",
|
||||||
}}, false},
|
}}, false},
|
||||||
|
{"ok ra endpoint id", fields{caURL, testX5CPath, testX5CKeyPath, "X5C"}, args{"doe", []string{"doe.org"}, &raInfo{
|
||||||
|
AuthorityID: "authority-id", EndpointID: "endpoint-id",
|
||||||
|
}}, false},
|
||||||
{"fail crt", fields{caURL, "", testX5CKeyPath, "X5C"}, args{"doe", []string{"doe.org"}, nil}, true},
|
{"fail crt", fields{caURL, "", testX5CKeyPath, "X5C"}, args{"doe", []string{"doe.org"}, nil}, true},
|
||||||
{"fail key", fields{caURL, testX5CPath, "", "X5C"}, args{"doe", []string{"doe.org"}, nil}, true},
|
{"fail key", fields{caURL, testX5CPath, "", "X5C"}, args{"doe", []string{"doe.org"}, nil}, true},
|
||||||
{"fail no signer", fields{caURL, testIssKeyPath, testIssPath, "X5C"}, args{"doe", []string{"doe.org"}, nil}, true},
|
{"fail no signer", fields{caURL, testIssKeyPath, testIssPath, "X5C"}, args{"doe", []string{"doe.org"}, nil}, true},
|
||||||
|
|
20
go.mod
20
go.mod
|
@ -4,17 +4,9 @@ go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go v0.100.2
|
cloud.google.com/go v0.100.2
|
||||||
cloud.google.com/go/kms v1.4.0
|
|
||||||
cloud.google.com/go/security v1.3.0
|
cloud.google.com/go/security v1.3.0
|
||||||
github.com/Azure/azure-sdk-for-go v65.0.0+incompatible
|
|
||||||
github.com/Azure/go-autorest/autorest v0.11.27
|
|
||||||
github.com/Azure/go-autorest/autorest/azure/auth v0.5.11
|
|
||||||
github.com/Azure/go-autorest/autorest/date v0.3.0
|
|
||||||
github.com/Masterminds/sprig/v3 v3.2.2
|
github.com/Masterminds/sprig/v3 v3.2.2
|
||||||
github.com/ThalesIgnite/crypto11 v1.2.5
|
|
||||||
github.com/aws/aws-sdk-go v1.44.37
|
|
||||||
github.com/go-chi/chi v4.0.2+incompatible
|
github.com/go-chi/chi v4.0.2+incompatible
|
||||||
github.com/go-piv/piv-go v1.10.0
|
|
||||||
github.com/golang/mock v1.6.0
|
github.com/golang/mock v1.6.0
|
||||||
github.com/google/go-cmp v0.5.8
|
github.com/google/go-cmp v0.5.8
|
||||||
github.com/google/uuid v1.3.0
|
github.com/google/uuid v1.3.0
|
||||||
|
@ -34,8 +26,8 @@ require (
|
||||||
github.com/urfave/cli v1.22.4
|
github.com/urfave/cli v1.22.4
|
||||||
go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352
|
go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352
|
||||||
go.step.sm/cli-utils v0.7.3
|
go.step.sm/cli-utils v0.7.3
|
||||||
go.step.sm/crypto v0.17.0
|
go.step.sm/crypto v0.17.1
|
||||||
go.step.sm/linkedca v0.17.0
|
go.step.sm/linkedca v0.17.1
|
||||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3
|
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3
|
||||||
golang.org/x/net v0.0.0-20220607020251-c690dde0001d
|
golang.org/x/net v0.0.0-20220607020251-c690dde0001d
|
||||||
google.golang.org/api v0.84.0
|
google.golang.org/api v0.84.0
|
||||||
|
@ -48,19 +40,26 @@ require (
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go/compute v1.6.1 // indirect
|
cloud.google.com/go/compute v1.6.1 // indirect
|
||||||
cloud.google.com/go/iam v0.1.0 // indirect
|
cloud.google.com/go/iam v0.1.0 // indirect
|
||||||
|
cloud.google.com/go/kms v1.4.0 // indirect
|
||||||
filippo.io/edwards25519 v1.0.0-rc.1 // indirect
|
filippo.io/edwards25519 v1.0.0-rc.1 // indirect
|
||||||
github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect
|
github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect
|
||||||
|
github.com/Azure/azure-sdk-for-go v65.0.0+incompatible // indirect
|
||||||
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
|
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
|
||||||
|
github.com/Azure/go-autorest/autorest v0.11.27 // indirect
|
||||||
github.com/Azure/go-autorest/autorest/adal v0.9.18 // indirect
|
github.com/Azure/go-autorest/autorest/adal v0.9.18 // indirect
|
||||||
|
github.com/Azure/go-autorest/autorest/azure/auth v0.5.11 // indirect
|
||||||
github.com/Azure/go-autorest/autorest/azure/cli v0.4.5 // indirect
|
github.com/Azure/go-autorest/autorest/azure/cli v0.4.5 // indirect
|
||||||
|
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
|
||||||
github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
|
github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
|
||||||
github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect
|
github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect
|
||||||
github.com/Azure/go-autorest/logger v0.2.1 // indirect
|
github.com/Azure/go-autorest/logger v0.2.1 // indirect
|
||||||
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
|
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
|
||||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||||
github.com/Masterminds/semver/v3 v3.1.1 // indirect
|
github.com/Masterminds/semver/v3 v3.1.1 // indirect
|
||||||
|
github.com/ThalesIgnite/crypto11 v1.2.5 // indirect
|
||||||
github.com/armon/go-metrics v0.3.9 // indirect
|
github.com/armon/go-metrics v0.3.9 // indirect
|
||||||
github.com/armon/go-radix v1.0.0 // indirect
|
github.com/armon/go-radix v1.0.0 // indirect
|
||||||
|
github.com/aws/aws-sdk-go v1.44.37 // indirect
|
||||||
github.com/cenkalti/backoff/v3 v3.0.0 // indirect
|
github.com/cenkalti/backoff/v3 v3.0.0 // indirect
|
||||||
github.com/cespare/xxhash v1.1.0 // indirect
|
github.com/cespare/xxhash v1.1.0 // indirect
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect
|
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect
|
||||||
|
@ -75,6 +74,7 @@ require (
|
||||||
github.com/fatih/color v1.9.0 // indirect
|
github.com/fatih/color v1.9.0 // indirect
|
||||||
github.com/go-kit/kit v0.10.0 // indirect
|
github.com/go-kit/kit v0.10.0 // indirect
|
||||||
github.com/go-logfmt/logfmt v0.5.0 // indirect
|
github.com/go-logfmt/logfmt v0.5.0 // indirect
|
||||||
|
github.com/go-piv/piv-go v1.10.0 // indirect
|
||||||
github.com/go-sql-driver/mysql v1.6.0 // indirect
|
github.com/go-sql-driver/mysql v1.6.0 // indirect
|
||||||
github.com/golang-jwt/jwt/v4 v4.2.0 // indirect
|
github.com/golang-jwt/jwt/v4 v4.2.0 // indirect
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||||
|
|
8
go.sum
8
go.sum
|
@ -767,10 +767,10 @@ go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqe
|
||||||
go.step.sm/cli-utils v0.7.3 h1:IA12IaiXVCI18yOFVQuvMpyvjL8wuwUn1yO+KhAVAr0=
|
go.step.sm/cli-utils v0.7.3 h1:IA12IaiXVCI18yOFVQuvMpyvjL8wuwUn1yO+KhAVAr0=
|
||||||
go.step.sm/cli-utils v0.7.3/go.mod h1:RJRwbBLqzs5nrepQLAV9FuT3fVpWz66tKzLIB7Izpfk=
|
go.step.sm/cli-utils v0.7.3/go.mod h1:RJRwbBLqzs5nrepQLAV9FuT3fVpWz66tKzLIB7Izpfk=
|
||||||
go.step.sm/crypto v0.9.0/go.mod h1:+CYG05Mek1YDqi5WK0ERc6cOpKly2i/a5aZmU1sfGj0=
|
go.step.sm/crypto v0.9.0/go.mod h1:+CYG05Mek1YDqi5WK0ERc6cOpKly2i/a5aZmU1sfGj0=
|
||||||
go.step.sm/crypto v0.17.0 h1:qaLUbWygcMRMxrsz91jL5ytHIsIMABFYX6TkU+V8Pq8=
|
go.step.sm/crypto v0.17.1 h1:uKpJNvzVy/GKR28hJbW8VCbfcKKBDnGNBYCKhAp2TSg=
|
||||||
go.step.sm/crypto v0.17.0/go.mod h1:2oZdJ4ZUqPv5q8wz6yN4Qfsdcu2+eRaob4q1E5Azavs=
|
go.step.sm/crypto v0.17.1/go.mod h1:FXFiLBUsoE0OGz8JTjxhYU1rwKKNgVIb5izZTUMdc/8=
|
||||||
go.step.sm/linkedca v0.17.0 h1:90XYS0cPCVilsS1udTOph7TVnsNVVPK/gb66VIAP4RU=
|
go.step.sm/linkedca v0.17.1 h1:LSP3kGGeVkOAoDWoqg89tko6mpvJKTRcOHfrEOnPsNc=
|
||||||
go.step.sm/linkedca v0.17.0/go.mod h1:W59ucS4vFpuR0g4PtkGbbtXAwxbDEnNCg+ovkej1ANM=
|
go.step.sm/linkedca v0.17.1/go.mod h1:qSuYlIIhvPmA2+DSSS03E2IXhbXWTLW61Xh9zDQJ3VM=
|
||||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
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.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
|
|
Loading…
Reference in a new issue