summaryrefslogtreecommitdiff
path: root/vendor/github.com/smallstep
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/smallstep')
-rw-r--r--vendor/github.com/smallstep/certificates/acme/account.go1
-rw-r--r--vendor/github.com/smallstep/certificates/acme/api/account.go47
-rw-r--r--vendor/github.com/smallstep/certificates/acme/api/handler.go38
-rw-r--r--vendor/github.com/smallstep/certificates/acme/api/middleware.go98
-rw-r--r--vendor/github.com/smallstep/certificates/acme/api/order.go174
-rw-r--r--vendor/github.com/smallstep/certificates/acme/api/revoke.go38
-rw-r--r--vendor/github.com/smallstep/certificates/acme/challenge.go496
-rw-r--r--vendor/github.com/smallstep/certificates/acme/db.go74
-rw-r--r--vendor/github.com/smallstep/certificates/acme/db/nosql/account.go3
-rw-r--r--vendor/github.com/smallstep/certificates/acme/db/nosql/challenge.go3
-rw-r--r--vendor/github.com/smallstep/certificates/acme/db/nosql/nosql.go6
-rw-r--r--vendor/github.com/smallstep/certificates/acme/db/nosql/order.go15
-rw-r--r--vendor/github.com/smallstep/certificates/acme/db/nosql/wire.go121
-rw-r--r--vendor/github.com/smallstep/certificates/acme/errors.go22
-rw-r--r--vendor/github.com/smallstep/certificates/acme/linker.go6
-rw-r--r--vendor/github.com/smallstep/certificates/acme/order.go180
-rw-r--r--vendor/github.com/smallstep/certificates/acme/wire/id.go91
-rw-r--r--vendor/github.com/smallstep/certificates/api/api.go84
-rw-r--r--vendor/github.com/smallstep/certificates/api/crl.go4
-rw-r--r--vendor/github.com/smallstep/certificates/api/log/log.go34
-rw-r--r--vendor/github.com/smallstep/certificates/api/read/read.go4
-rw-r--r--vendor/github.com/smallstep/certificates/api/rekey.go10
-rw-r--r--vendor/github.com/smallstep/certificates/api/render/render.go22
-rw-r--r--vendor/github.com/smallstep/certificates/api/renew.go7
-rw-r--r--vendor/github.com/smallstep/certificates/api/revoke.go14
-rw-r--r--vendor/github.com/smallstep/certificates/api/sign.go10
-rw-r--r--vendor/github.com/smallstep/certificates/api/ssh.go97
-rw-r--r--vendor/github.com/smallstep/certificates/api/sshRekey.go16
-rw-r--r--vendor/github.com/smallstep/certificates/api/sshRenew.go14
-rw-r--r--vendor/github.com/smallstep/certificates/api/sshRevoke.go10
-rw-r--r--vendor/github.com/smallstep/certificates/authority/admin/errors.go4
-rw-r--r--vendor/github.com/smallstep/certificates/authority/authority.go15
-rw-r--r--vendor/github.com/smallstep/certificates/authority/authorize.go4
-rw-r--r--vendor/github.com/smallstep/certificates/authority/export.go8
-rw-r--r--vendor/github.com/smallstep/certificates/authority/http_client.go34
-rw-r--r--vendor/github.com/smallstep/certificates/authority/linkedca.go17
-rw-r--r--vendor/github.com/smallstep/certificates/authority/policy/engine.go6
-rw-r--r--vendor/github.com/smallstep/certificates/authority/policy/policy.go4
-rw-r--r--vendor/github.com/smallstep/certificates/authority/provisioner/acme.go66
-rw-r--r--vendor/github.com/smallstep/certificates/authority/provisioner/aws.go2
-rw-r--r--vendor/github.com/smallstep/certificates/authority/provisioner/aws_certificates.pem452
-rw-r--r--vendor/github.com/smallstep/certificates/authority/provisioner/azure.go6
-rw-r--r--vendor/github.com/smallstep/certificates/authority/provisioner/claims.go24
-rw-r--r--vendor/github.com/smallstep/certificates/authority/provisioner/controller.go11
-rw-r--r--vendor/github.com/smallstep/certificates/authority/provisioner/gcp.go110
-rw-r--r--vendor/github.com/smallstep/certificates/authority/provisioner/jwk.go18
-rw-r--r--vendor/github.com/smallstep/certificates/authority/provisioner/keystore.go12
-rw-r--r--vendor/github.com/smallstep/certificates/authority/provisioner/method.go14
-rw-r--r--vendor/github.com/smallstep/certificates/authority/provisioner/nebula.go24
-rw-r--r--vendor/github.com/smallstep/certificates/authority/provisioner/oidc.go26
-rw-r--r--vendor/github.com/smallstep/certificates/authority/provisioner/options.go18
-rw-r--r--vendor/github.com/smallstep/certificates/authority/provisioner/provisioner.go32
-rw-r--r--vendor/github.com/smallstep/certificates/authority/provisioner/scep.go27
-rw-r--r--vendor/github.com/smallstep/certificates/authority/provisioner/sign_options.go94
-rw-r--r--vendor/github.com/smallstep/certificates/authority/provisioner/sign_ssh_options.go25
-rw-r--r--vendor/github.com/smallstep/certificates/authority/provisioner/ssh_options.go3
-rw-r--r--vendor/github.com/smallstep/certificates/authority/provisioner/timeduration.go11
-rw-r--r--vendor/github.com/smallstep/certificates/authority/provisioner/webhook.go6
-rw-r--r--vendor/github.com/smallstep/certificates/authority/provisioner/wire/dpop_options.go49
-rw-r--r--vendor/github.com/smallstep/certificates/authority/provisioner/wire/oidc_options.go179
-rw-r--r--vendor/github.com/smallstep/certificates/authority/provisioner/wire/wire_options.go51
-rw-r--r--vendor/github.com/smallstep/certificates/authority/provisioner/x5c.go16
-rw-r--r--vendor/github.com/smallstep/certificates/authority/provisioners.go37
-rw-r--r--vendor/github.com/smallstep/certificates/authority/root.go23
-rw-r--r--vendor/github.com/smallstep/certificates/authority/ssh.go32
-rw-r--r--vendor/github.com/smallstep/certificates/authority/tls.go19
-rw-r--r--vendor/github.com/smallstep/certificates/cas/apiv1/services.go10
-rw-r--r--vendor/github.com/smallstep/certificates/cas/softcas/softcas.go7
-rw-r--r--vendor/github.com/smallstep/certificates/errs/error.go9
-rw-r--r--vendor/github.com/smallstep/certificates/logging/handler.go48
-rw-r--r--vendor/github.com/smallstep/certificates/policy/engine.go2
-rw-r--r--vendor/github.com/smallstep/certificates/scep/authority.go11
-rw-r--r--vendor/github.com/smallstep/certificates/scep/provisioner.go2
-rw-r--r--vendor/github.com/smallstep/certificates/scep/scep.go9
-rw-r--r--vendor/github.com/smallstep/certificates/templates/templates.go5
-rw-r--r--vendor/github.com/smallstep/certificates/templates/values.go4
-rw-r--r--vendor/github.com/smallstep/certificates/webhook/types.go16
-rw-r--r--vendor/github.com/smallstep/cli-utils/LICENSE201
-rw-r--r--vendor/github.com/smallstep/cli-utils/command/command.go45
-rw-r--r--vendor/github.com/smallstep/cli-utils/errs/errs.go330
-rw-r--r--vendor/github.com/smallstep/cli-utils/fileutil/file.go121
-rw-r--r--vendor/github.com/smallstep/cli-utils/fileutil/write.go232
-rw-r--r--vendor/github.com/smallstep/cli-utils/pkg/blackfriday/LICENSE.txt29
-rw-r--r--vendor/github.com/smallstep/cli-utils/pkg/blackfriday/README.md283
-rw-r--r--vendor/github.com/smallstep/cli-utils/pkg/blackfriday/block.go1559
-rw-r--r--vendor/github.com/smallstep/cli-utils/pkg/blackfriday/doc.go18
-rw-r--r--vendor/github.com/smallstep/cli-utils/pkg/blackfriday/esc.go34
-rw-r--r--vendor/github.com/smallstep/cli-utils/pkg/blackfriday/html.go941
-rw-r--r--vendor/github.com/smallstep/cli-utils/pkg/blackfriday/inline.go1217
-rw-r--r--vendor/github.com/smallstep/cli-utils/pkg/blackfriday/markdown.go945
-rw-r--r--vendor/github.com/smallstep/cli-utils/pkg/blackfriday/node.go355
-rw-r--r--vendor/github.com/smallstep/cli-utils/pkg/blackfriday/smartypants.go458
-rw-r--r--vendor/github.com/smallstep/cli-utils/step/config.go220
-rw-r--r--vendor/github.com/smallstep/cli-utils/step/context.go565
-rw-r--r--vendor/github.com/smallstep/cli-utils/ui/options.go172
-rw-r--r--vendor/github.com/smallstep/cli-utils/ui/templates.go93
-rw-r--r--vendor/github.com/smallstep/cli-utils/ui/ui.go334
-rw-r--r--vendor/github.com/smallstep/cli-utils/ui/ui_other.go8
-rw-r--r--vendor/github.com/smallstep/cli-utils/ui/ui_windows.go51
-rw-r--r--vendor/github.com/smallstep/cli-utils/ui/validators.go75
-rw-r--r--vendor/github.com/smallstep/cli-utils/usage/css.go764
-rw-r--r--vendor/github.com/smallstep/cli-utils/usage/help.go191
-rw-r--r--vendor/github.com/smallstep/cli-utils/usage/html.go351
-rw-r--r--vendor/github.com/smallstep/cli-utils/usage/printer.go235
-rw-r--r--vendor/github.com/smallstep/cli-utils/usage/renderer.go373
-rw-r--r--vendor/github.com/smallstep/cli-utils/usage/report.go148
-rw-r--r--vendor/github.com/smallstep/cli-utils/usage/usage.go214
-rw-r--r--vendor/github.com/smallstep/nosql/postgresql/postgresql.go4
-rw-r--r--vendor/github.com/smallstep/pkcs7/.gitignore4
-rw-r--r--vendor/github.com/smallstep/pkcs7/README.md28
-rw-r--r--vendor/github.com/smallstep/pkcs7/ber.go21
-rw-r--r--vendor/github.com/smallstep/pkcs7/encrypt.go3
-rw-r--r--vendor/github.com/smallstep/pkcs7/internal/legacy/x509/debug.go14
-rw-r--r--vendor/github.com/smallstep/pkcs7/internal/legacy/x509/doc.go14
-rw-r--r--vendor/github.com/smallstep/pkcs7/internal/legacy/x509/oid.go377
-rw-r--r--vendor/github.com/smallstep/pkcs7/internal/legacy/x509/parser.go1027
-rw-r--r--vendor/github.com/smallstep/pkcs7/internal/legacy/x509/pkcs1.go15
-rw-r--r--vendor/github.com/smallstep/pkcs7/internal/legacy/x509/verify.go193
-rw-r--r--vendor/github.com/smallstep/pkcs7/internal/legacy/x509/x509.go488
-rw-r--r--vendor/github.com/smallstep/pkcs7/pkcs7.go46
-rw-r--r--vendor/github.com/smallstep/pkcs7/verify.go33
-rw-r--r--vendor/github.com/smallstep/pkcs7/verify_test_dsa.go182
-rw-r--r--vendor/github.com/smallstep/scep/scep.go47
-rw-r--r--vendor/github.com/smallstep/scep/x509util/x509util.go2
124 files changed, 742 insertions, 15659 deletions
diff --git a/vendor/github.com/smallstep/certificates/acme/account.go b/vendor/github.com/smallstep/certificates/acme/account.go
index 246e031..38cca21 100644
--- a/vendor/github.com/smallstep/certificates/acme/account.go
+++ b/vendor/github.com/smallstep/certificates/acme/account.go
@@ -21,7 +21,6 @@ type Account struct {
OrdersURL string `json:"orders"`
ExternalAccountBinding interface{} `json:"externalAccountBinding,omitempty"`
LocationPrefix string `json:"-"`
- ProvisionerID string `json:"-"`
ProvisionerName string `json:"-"`
}
diff --git a/vendor/github.com/smallstep/certificates/acme/api/account.go b/vendor/github.com/smallstep/certificates/acme/api/account.go
index 3114dcb..25d923c 100644
--- a/vendor/github.com/smallstep/certificates/acme/api/account.go
+++ b/vendor/github.com/smallstep/certificates/acme/api/account.go
@@ -82,23 +82,23 @@ func NewAccount(w http.ResponseWriter, r *http.Request) {
payload, err := payloadFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
var nar NewAccountRequest
if err := json.Unmarshal(payload.value, &nar); err != nil {
- render.Error(w, r, acme.WrapError(acme.ErrorMalformedType, err,
+ render.Error(w, acme.WrapError(acme.ErrorMalformedType, err,
"failed to unmarshal new-account request payload"))
return
}
if err := nar.Validate(); err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
prov, err := acmeProvisionerFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
@@ -108,26 +108,26 @@ func NewAccount(w http.ResponseWriter, r *http.Request) {
var acmeErr *acme.Error
if !errors.As(err, &acmeErr) || acmeErr.Status != http.StatusBadRequest {
// Something went wrong ...
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
// Account does not exist //
if nar.OnlyReturnExisting {
- render.Error(w, r, acme.NewError(acme.ErrorAccountDoesNotExistType,
+ render.Error(w, acme.NewError(acme.ErrorAccountDoesNotExistType,
"account does not exist"))
return
}
jwk, err := jwkFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
eak, err := validateExternalAccountBinding(ctx, &nar)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
@@ -136,21 +136,20 @@ func NewAccount(w http.ResponseWriter, r *http.Request) {
Contact: nar.Contact,
Status: acme.StatusValid,
LocationPrefix: getAccountLocationPath(ctx, linker, ""),
- ProvisionerID: prov.ID,
- ProvisionerName: prov.Name,
+ ProvisionerName: prov.GetName(),
}
if err := db.CreateAccount(ctx, acc); err != nil {
- render.Error(w, r, acme.WrapErrorISE(err, "error creating account"))
+ render.Error(w, acme.WrapErrorISE(err, "error creating account"))
return
}
if eak != nil { // means that we have a (valid) External Account Binding key that should be bound, updated and sent in the response
if err := eak.BindTo(acc); err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
if err := db.UpdateExternalAccountKey(ctx, prov.ID, eak); err != nil {
- render.Error(w, r, acme.WrapErrorISE(err, "error updating external account binding key"))
+ render.Error(w, acme.WrapErrorISE(err, "error updating external account binding key"))
return
}
acc.ExternalAccountBinding = nar.ExternalAccountBinding
@@ -163,7 +162,7 @@ func NewAccount(w http.ResponseWriter, r *http.Request) {
linker.LinkAccount(ctx, acc)
w.Header().Set("Location", getAccountLocationPath(ctx, linker, acc.ID))
- render.JSONStatus(w, r, acc, httpStatus)
+ render.JSONStatus(w, acc, httpStatus)
}
// GetOrUpdateAccount is the api for updating an ACME account.
@@ -174,12 +173,12 @@ func GetOrUpdateAccount(w http.ResponseWriter, r *http.Request) {
acc, err := accountFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
payload, err := payloadFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
@@ -188,12 +187,12 @@ func GetOrUpdateAccount(w http.ResponseWriter, r *http.Request) {
if !payload.isPostAsGet {
var uar UpdateAccountRequest
if err := json.Unmarshal(payload.value, &uar); err != nil {
- render.Error(w, r, acme.WrapError(acme.ErrorMalformedType, err,
+ render.Error(w, acme.WrapError(acme.ErrorMalformedType, err,
"failed to unmarshal new-account request payload"))
return
}
if err := uar.Validate(); err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
if len(uar.Status) > 0 || len(uar.Contact) > 0 {
@@ -204,7 +203,7 @@ func GetOrUpdateAccount(w http.ResponseWriter, r *http.Request) {
}
if err := db.UpdateAccount(ctx, acc); err != nil {
- render.Error(w, r, acme.WrapErrorISE(err, "error updating account"))
+ render.Error(w, acme.WrapErrorISE(err, "error updating account"))
return
}
}
@@ -213,7 +212,7 @@ func GetOrUpdateAccount(w http.ResponseWriter, r *http.Request) {
linker.LinkAccount(ctx, acc)
w.Header().Set("Location", linker.GetLink(ctx, acme.AccountLinkType, acc.ID))
- render.JSON(w, r, acc)
+ render.JSON(w, acc)
}
func logOrdersByAccount(w http.ResponseWriter, oids []string) {
@@ -233,23 +232,23 @@ func GetOrdersByAccountID(w http.ResponseWriter, r *http.Request) {
acc, err := accountFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
accID := chi.URLParam(r, "accID")
if acc.ID != accID {
- render.Error(w, r, acme.NewError(acme.ErrorUnauthorizedType, "account ID '%s' does not match url param '%s'", acc.ID, accID))
+ render.Error(w, acme.NewError(acme.ErrorUnauthorizedType, "account ID '%s' does not match url param '%s'", acc.ID, accID))
return
}
orders, err := db.GetOrdersByAccountID(ctx, acc.ID)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
linker.LinkOrdersByAccountID(ctx, orders)
- render.JSON(w, r, orders)
+ render.JSON(w, orders)
logOrdersByAccount(w, orders)
}
diff --git a/vendor/github.com/smallstep/certificates/acme/api/handler.go b/vendor/github.com/smallstep/certificates/acme/api/handler.go
index 0722bd9..d2940f4 100644
--- a/vendor/github.com/smallstep/certificates/acme/api/handler.go
+++ b/vendor/github.com/smallstep/certificates/acme/api/handler.go
@@ -223,13 +223,13 @@ func GetDirectory(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
acmeProv, err := acmeProvisionerFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
linker := acme.MustLinkerFromContext(ctx)
- render.JSON(w, r, &Directory{
+ render.JSON(w, &Directory{
NewNonce: linker.GetLink(ctx, acme.NewNonceLinkType),
NewAccount: linker.GetLink(ctx, acme.NewAccountLinkType),
NewOrder: linker.GetLink(ctx, acme.NewOrderLinkType),
@@ -273,8 +273,8 @@ func shouldAddMetaObject(p *provisioner.ACME) bool {
// NotImplemented returns a 501 and is generally a placeholder for functionality which
// MAY be added at some point in the future but is not in any way a guarantee of such.
-func NotImplemented(w http.ResponseWriter, r *http.Request) {
- render.Error(w, r, acme.NewError(acme.ErrorNotImplementedType, "this API is not implemented"))
+func NotImplemented(w http.ResponseWriter, _ *http.Request) {
+ render.Error(w, acme.NewError(acme.ErrorNotImplementedType, "this API is not implemented"))
}
// GetAuthorization ACME api for retrieving an Authz.
@@ -285,28 +285,28 @@ func GetAuthorization(w http.ResponseWriter, r *http.Request) {
acc, err := accountFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
az, err := db.GetAuthorization(ctx, chi.URLParam(r, "authzID"))
if err != nil {
- render.Error(w, r, acme.WrapErrorISE(err, "error retrieving authorization"))
+ render.Error(w, acme.WrapErrorISE(err, "error retrieving authorization"))
return
}
if acc.ID != az.AccountID {
- render.Error(w, r, acme.NewError(acme.ErrorUnauthorizedType,
+ render.Error(w, acme.NewError(acme.ErrorUnauthorizedType,
"account '%s' does not own authorization '%s'", acc.ID, az.ID))
return
}
if err = az.UpdateStatus(ctx, db); err != nil {
- render.Error(w, r, acme.WrapErrorISE(err, "error updating authorization status"))
+ render.Error(w, acme.WrapErrorISE(err, "error updating authorization status"))
return
}
linker.LinkAuthorization(ctx, az)
w.Header().Set("Location", linker.GetLink(ctx, acme.AuthzLinkType, az.ID))
- render.JSON(w, r, az)
+ render.JSON(w, az)
}
// GetChallenge ACME api for retrieving a Challenge.
@@ -317,13 +317,13 @@ func GetChallenge(w http.ResponseWriter, r *http.Request) {
acc, err := accountFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
payload, err := payloadFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
@@ -336,22 +336,22 @@ func GetChallenge(w http.ResponseWriter, r *http.Request) {
azID := chi.URLParam(r, "authzID")
ch, err := db.GetChallenge(ctx, chi.URLParam(r, "chID"), azID)
if err != nil {
- render.Error(w, r, acme.WrapErrorISE(err, "error retrieving challenge"))
+ render.Error(w, acme.WrapErrorISE(err, "error retrieving challenge"))
return
}
ch.AuthorizationID = azID
if acc.ID != ch.AccountID {
- render.Error(w, r, acme.NewError(acme.ErrorUnauthorizedType,
+ render.Error(w, acme.NewError(acme.ErrorUnauthorizedType,
"account '%s' does not own challenge '%s'", acc.ID, ch.ID))
return
}
jwk, err := jwkFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
if err = ch.Validate(ctx, db, jwk, payload.value); err != nil {
- render.Error(w, r, acme.WrapErrorISE(err, "error validating challenge"))
+ render.Error(w, acme.WrapErrorISE(err, "error validating challenge"))
return
}
@@ -359,7 +359,7 @@ func GetChallenge(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Link", link(linker.GetLink(ctx, acme.AuthzLinkType, azID), "up"))
w.Header().Set("Location", linker.GetLink(ctx, acme.ChallengeLinkType, azID, ch.ID))
- render.JSON(w, r, ch)
+ render.JSON(w, ch)
}
// GetCertificate ACME api for retrieving a Certificate.
@@ -369,18 +369,18 @@ func GetCertificate(w http.ResponseWriter, r *http.Request) {
acc, err := accountFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
certID := chi.URLParam(r, "certID")
cert, err := db.GetCertificate(ctx, certID)
if err != nil {
- render.Error(w, r, acme.WrapErrorISE(err, "error retrieving certificate"))
+ render.Error(w, acme.WrapErrorISE(err, "error retrieving certificate"))
return
}
if cert.AccountID != acc.ID {
- render.Error(w, r, acme.NewError(acme.ErrorUnauthorizedType,
+ render.Error(w, acme.NewError(acme.ErrorUnauthorizedType,
"account '%s' does not own certificate '%s'", acc.ID, certID))
return
}
diff --git a/vendor/github.com/smallstep/certificates/acme/api/middleware.go b/vendor/github.com/smallstep/certificates/acme/api/middleware.go
index 628da7e..afccca7 100644
--- a/vendor/github.com/smallstep/certificates/acme/api/middleware.go
+++ b/vendor/github.com/smallstep/certificates/acme/api/middleware.go
@@ -36,7 +36,7 @@ func addNonce(next nextHTTP) nextHTTP {
db := acme.MustDatabaseFromContext(r.Context())
nonce, err := db.CreateNonce(r.Context())
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
w.Header().Set("Replay-Nonce", string(nonce))
@@ -64,7 +64,7 @@ func verifyContentType(next nextHTTP) nextHTTP {
return func(w http.ResponseWriter, r *http.Request) {
p, err := provisionerFromContext(r.Context())
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
@@ -88,7 +88,7 @@ func verifyContentType(next nextHTTP) nextHTTP {
return
}
}
- render.Error(w, r, acme.NewError(acme.ErrorMalformedType,
+ render.Error(w, acme.NewError(acme.ErrorMalformedType,
"expected content-type to be in %s, but got %s", expected, ct))
}
}
@@ -98,12 +98,12 @@ func parseJWS(next nextHTTP) nextHTTP {
return func(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
- render.Error(w, r, acme.WrapErrorISE(err, "failed to read request body"))
+ render.Error(w, acme.WrapErrorISE(err, "failed to read request body"))
return
}
jws, err := jose.ParseJWS(string(body))
if err != nil {
- render.Error(w, r, acme.WrapError(acme.ErrorMalformedType, err, "failed to parse JWS from request body"))
+ render.Error(w, acme.WrapError(acme.ErrorMalformedType, err, "failed to parse JWS from request body"))
return
}
ctx := context.WithValue(r.Context(), jwsContextKey, jws)
@@ -133,15 +133,15 @@ func validateJWS(next nextHTTP) nextHTTP {
jws, err := jwsFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
if len(jws.Signatures) == 0 {
- render.Error(w, r, acme.NewError(acme.ErrorMalformedType, "request body does not contain a signature"))
+ render.Error(w, acme.NewError(acme.ErrorMalformedType, "request body does not contain a signature"))
return
}
if len(jws.Signatures) > 1 {
- render.Error(w, r, acme.NewError(acme.ErrorMalformedType, "request body contains more than one signature"))
+ render.Error(w, acme.NewError(acme.ErrorMalformedType, "request body contains more than one signature"))
return
}
@@ -152,7 +152,7 @@ func validateJWS(next nextHTTP) nextHTTP {
uh.Algorithm != "" ||
uh.Nonce != "" ||
len(uh.ExtraHeaders) > 0 {
- render.Error(w, r, acme.NewError(acme.ErrorMalformedType, "unprotected header must not be used"))
+ render.Error(w, acme.NewError(acme.ErrorMalformedType, "unprotected header must not be used"))
return
}
hdr := sig.Protected
@@ -162,13 +162,13 @@ func validateJWS(next nextHTTP) nextHTTP {
switch k := hdr.JSONWebKey.Key.(type) {
case *rsa.PublicKey:
if k.Size() < keyutil.MinRSAKeyBytes {
- render.Error(w, r, acme.NewError(acme.ErrorMalformedType,
+ render.Error(w, acme.NewError(acme.ErrorMalformedType,
"rsa keys must be at least %d bits (%d bytes) in size",
8*keyutil.MinRSAKeyBytes, keyutil.MinRSAKeyBytes))
return
}
default:
- render.Error(w, r, acme.NewError(acme.ErrorMalformedType,
+ render.Error(w, acme.NewError(acme.ErrorMalformedType,
"jws key type and algorithm do not match"))
return
}
@@ -176,35 +176,35 @@ func validateJWS(next nextHTTP) nextHTTP {
case jose.ES256, jose.ES384, jose.ES512, jose.EdDSA:
// we good
default:
- render.Error(w, r, acme.NewError(acme.ErrorBadSignatureAlgorithmType, "unsuitable algorithm: %s", hdr.Algorithm))
+ render.Error(w, acme.NewError(acme.ErrorBadSignatureAlgorithmType, "unsuitable algorithm: %s", hdr.Algorithm))
return
}
// Check the validity/freshness of the Nonce.
if err := db.DeleteNonce(ctx, acme.Nonce(hdr.Nonce)); err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
// Check that the JWS url matches the requested url.
jwsURL, ok := hdr.ExtraHeaders["url"].(string)
if !ok {
- render.Error(w, r, acme.NewError(acme.ErrorMalformedType, "jws missing url protected header"))
+ render.Error(w, acme.NewError(acme.ErrorMalformedType, "jws missing url protected header"))
return
}
reqURL := &url.URL{Scheme: "https", Host: r.Host, Path: r.URL.Path}
if jwsURL != reqURL.String() {
- render.Error(w, r, acme.NewError(acme.ErrorMalformedType,
+ render.Error(w, acme.NewError(acme.ErrorMalformedType,
"url header in JWS (%s) does not match request url (%s)", jwsURL, reqURL))
return
}
if hdr.JSONWebKey != nil && hdr.KeyID != "" {
- render.Error(w, r, acme.NewError(acme.ErrorMalformedType, "jwk and kid are mutually exclusive"))
+ render.Error(w, acme.NewError(acme.ErrorMalformedType, "jwk and kid are mutually exclusive"))
return
}
if hdr.JSONWebKey == nil && hdr.KeyID == "" {
- render.Error(w, r, acme.NewError(acme.ErrorMalformedType, "either jwk or kid must be defined in jws protected header"))
+ render.Error(w, acme.NewError(acme.ErrorMalformedType, "either jwk or kid must be defined in jws protected header"))
return
}
next(w, r)
@@ -221,23 +221,23 @@ func extractJWK(next nextHTTP) nextHTTP {
jws, err := jwsFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
jwk := jws.Signatures[0].Protected.JSONWebKey
if jwk == nil {
- render.Error(w, r, acme.NewError(acme.ErrorMalformedType, "jwk expected in protected header"))
+ render.Error(w, acme.NewError(acme.ErrorMalformedType, "jwk expected in protected header"))
return
}
if !jwk.Valid() {
- render.Error(w, r, acme.NewError(acme.ErrorMalformedType, "invalid jwk in protected header"))
+ render.Error(w, acme.NewError(acme.ErrorMalformedType, "invalid jwk in protected header"))
return
}
// Overwrite KeyID with the JWK thumbprint.
jwk.KeyID, err = acme.KeyToID(jwk)
if err != nil {
- render.Error(w, r, acme.WrapErrorISE(err, "error getting KeyID from JWK"))
+ render.Error(w, acme.WrapErrorISE(err, "error getting KeyID from JWK"))
return
}
@@ -247,15 +247,15 @@ func extractJWK(next nextHTTP) nextHTTP {
// Get Account OR continue to generate a new one OR continue Revoke with certificate private key
acc, err := db.GetAccountByKeyID(ctx, jwk.KeyID)
switch {
- case acme.IsErrNotFound(err):
+ case errors.Is(err, acme.ErrNotFound):
// For NewAccount and Revoke requests ...
break
case err != nil:
- render.Error(w, r, err)
+ render.Error(w, err)
return
default:
if !acc.IsValid() {
- render.Error(w, r, acme.NewError(acme.ErrorUnauthorizedType, "account is not active"))
+ render.Error(w, acme.NewError(acme.ErrorUnauthorizedType, "account is not active"))
return
}
ctx = context.WithValue(ctx, accContextKey, acc)
@@ -274,11 +274,11 @@ func checkPrerequisites(next nextHTTP) nextHTTP {
if ok {
ok, err := checkFunc(ctx)
if err != nil {
- render.Error(w, r, acme.WrapErrorISE(err, "error checking acme provisioner prerequisites"))
+ render.Error(w, acme.WrapErrorISE(err, "error checking acme provisioner prerequisites"))
return
}
if !ok {
- render.Error(w, r, acme.NewError(acme.ErrorNotImplementedType, "acme provisioner configuration lacks prerequisites"))
+ render.Error(w, acme.NewError(acme.ErrorNotImplementedType, "acme provisioner configuration lacks prerequisites"))
return
}
}
@@ -296,13 +296,13 @@ func lookupJWK(next nextHTTP) nextHTTP {
jws, err := jwsFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
kid := jws.Signatures[0].Protected.KeyID
if kid == "" {
- render.Error(w, r, acme.NewError(acme.ErrorMalformedType, "signature missing 'kid'"))
+ render.Error(w, acme.NewError(acme.ErrorMalformedType, "signature missing 'kid'"))
return
}
@@ -310,14 +310,14 @@ func lookupJWK(next nextHTTP) nextHTTP {
acc, err := db.GetAccount(ctx, accID)
switch {
case acme.IsErrNotFound(err):
- render.Error(w, r, acme.NewError(acme.ErrorAccountDoesNotExistType, "account with ID '%s' not found", accID))
+ render.Error(w, acme.NewError(acme.ErrorAccountDoesNotExistType, "account with ID '%s' not found", accID))
return
case err != nil:
- render.Error(w, r, err)
+ render.Error(w, err)
return
default:
if !acc.IsValid() {
- render.Error(w, r, acme.NewError(acme.ErrorUnauthorizedType, "account is not active"))
+ render.Error(w, acme.NewError(acme.ErrorUnauthorizedType, "account is not active"))
return
}
@@ -325,7 +325,7 @@ func lookupJWK(next nextHTTP) nextHTTP {
if kid != storedLocation {
// ACME accounts should have a stored location equivalent to the
// kid in the ACME request.
- render.Error(w, r, acme.NewError(acme.ErrorUnauthorizedType,
+ render.Error(w, acme.NewError(acme.ErrorUnauthorizedType,
"kid does not match stored account location; expected %s, but got %s",
storedLocation, kid))
return
@@ -334,16 +334,14 @@ func lookupJWK(next nextHTTP) nextHTTP {
// Verify that the provisioner with which the account was created
// matches the provisioner in the request URL.
reqProv := acme.MustProvisionerFromContext(ctx)
- switch {
- case acc.ProvisionerID == "" && acc.ProvisionerName != reqProv.GetName():
- render.Error(w, r, acme.NewError(acme.ErrorUnauthorizedType,
- "account provisioner does not match requested provisioner; account provisioner = %s, requested provisioner = %s",
- acc.ProvisionerName, reqProv.GetName()))
- return
- case acc.ProvisionerID != "" && acc.ProvisionerID != reqProv.GetID():
- render.Error(w, r, acme.NewError(acme.ErrorUnauthorizedType,
+ reqProvName := reqProv.GetName()
+ accProvName := acc.ProvisionerName
+ if reqProvName != accProvName {
+ // Provisioner in the URL must match the provisioner with
+ // which the account was created.
+ render.Error(w, acme.NewError(acme.ErrorUnauthorizedType,
"account provisioner does not match requested provisioner; account provisioner = %s, requested provisioner = %s",
- acc.ProvisionerID, reqProv.GetID()))
+ accProvName, reqProvName))
return
}
} else {
@@ -355,7 +353,7 @@ func lookupJWK(next nextHTTP) nextHTTP {
linker := acme.MustLinkerFromContext(ctx)
kidPrefix := linker.GetLink(ctx, acme.AccountLinkType, "")
if !strings.HasPrefix(kid, kidPrefix) {
- render.Error(w, r, acme.NewError(acme.ErrorMalformedType,
+ render.Error(w, acme.NewError(acme.ErrorMalformedType,
"kid does not have required prefix; expected %s, but got %s",
kidPrefix, kid))
return
@@ -376,7 +374,7 @@ func extractOrLookupJWK(next nextHTTP) nextHTTP {
ctx := r.Context()
jws, err := jwsFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
@@ -412,16 +410,16 @@ func verifyAndExtractJWSPayload(next nextHTTP) nextHTTP {
ctx := r.Context()
jws, err := jwsFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
jwk, err := jwkFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
if jwk.Algorithm != "" && jwk.Algorithm != jws.Signatures[0].Protected.Algorithm {
- render.Error(w, r, acme.NewError(acme.ErrorMalformedType, "verifier and signature algorithm do not match"))
+ render.Error(w, acme.NewError(acme.ErrorMalformedType, "verifier and signature algorithm do not match"))
return
}
@@ -430,11 +428,11 @@ func verifyAndExtractJWSPayload(next nextHTTP) nextHTTP {
case errors.Is(err, jose.ErrCryptoFailure):
payload, err = retryVerificationWithPatchedSignatures(jws, jwk)
if err != nil {
- render.Error(w, r, acme.WrapError(acme.ErrorMalformedType, err, "error verifying jws with patched signature(s)"))
+ render.Error(w, acme.WrapError(acme.ErrorMalformedType, err, "error verifying jws with patched signature(s)"))
return
}
case err != nil:
- render.Error(w, r, acme.WrapError(acme.ErrorMalformedType, err, "error verifying jws"))
+ render.Error(w, acme.WrapError(acme.ErrorMalformedType, err, "error verifying jws"))
return
}
@@ -551,11 +549,11 @@ func isPostAsGet(next nextHTTP) nextHTTP {
return func(w http.ResponseWriter, r *http.Request) {
payload, err := payloadFromContext(r.Context())
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
if !payload.isPostAsGet {
- render.Error(w, r, acme.NewError(acme.ErrorMalformedType, "expected POST-as-GET"))
+ render.Error(w, acme.NewError(acme.ErrorMalformedType, "expected POST-as-GET"))
return
}
next(w, r)
diff --git a/vendor/github.com/smallstep/certificates/acme/api/order.go b/vendor/github.com/smallstep/certificates/acme/api/order.go
index a75a4d8..b207f87 100644
--- a/vendor/github.com/smallstep/certificates/acme/api/order.go
+++ b/vendor/github.com/smallstep/certificates/acme/api/order.go
@@ -5,7 +5,6 @@ import (
"crypto/x509"
"encoding/base64"
"encoding/json"
- "fmt"
"net"
"net/http"
"strings"
@@ -17,7 +16,6 @@ import (
"go.step.sm/crypto/x509util"
"github.com/smallstep/certificates/acme"
- "github.com/smallstep/certificates/acme/wire"
"github.com/smallstep/certificates/api/render"
"github.com/smallstep/certificates/authority/policy"
"github.com/smallstep/certificates/authority/provisioner"
@@ -50,86 +48,16 @@ func (n *NewOrderRequest) Validate() error {
if id.Value == "" {
return acme.NewError(acme.ErrorMalformedType, "permanent identifier cannot be empty")
}
- case acme.WireUser, acme.WireDevice:
- // validation of Wire identifiers is performed in `validateWireIdentifiers`, but
- // marked here as known and supported types.
- continue
default:
return acme.NewError(acme.ErrorMalformedType, "identifier type unsupported: %s", id.Type)
}
- }
- if err := n.validateWireIdentifiers(); err != nil {
- return acme.WrapError(acme.ErrorMalformedType, err, "failed validating Wire identifiers")
+ // TODO(hs): add some validations for DNS domains?
+ // TODO(hs): combine the errors from this with allow/deny policy, like example error in https://datatracker.ietf.org/doc/html/rfc8555#section-6.7.1
}
-
- // TODO(hs): add some validations for DNS domains?
- // TODO(hs): combine the errors from this with allow/deny policy, like example error in https://datatracker.ietf.org/doc/html/rfc8555#section-6.7.1
-
return nil
}
-func (n *NewOrderRequest) validateWireIdentifiers() error {
- if !n.hasWireIdentifiers() {
- return nil
- }
-
- userIdentifiers := identifiersOfType(acme.WireUser, n.Identifiers)
- deviceIdentifiers := identifiersOfType(acme.WireDevice, n.Identifiers)
-
- if len(userIdentifiers) != 1 {
- return fmt.Errorf("expected exactly one Wire UserID identifier; got %d", len(userIdentifiers))
- }
- if len(deviceIdentifiers) != 1 {
- return fmt.Errorf("expected exactly one Wire DeviceID identifier, got %d", len(deviceIdentifiers))
- }
-
- wireUserID, err := wire.ParseUserID(userIdentifiers[0].Value)
- if err != nil {
- return fmt.Errorf("failed parsing Wire UserID: %w", err)
- }
-
- wireDeviceID, err := wire.ParseDeviceID(deviceIdentifiers[0].Value)
- if err != nil {
- return fmt.Errorf("failed parsing Wire DeviceID: %w", err)
- }
- if _, err := wire.ParseClientID(wireDeviceID.ClientID); err != nil {
- return fmt.Errorf("invalid Wire client ID %q: %w", wireDeviceID.ClientID, err)
- }
-
- switch {
- case wireUserID.Domain != wireDeviceID.Domain:
- return fmt.Errorf("UserID domain %q does not match DeviceID domain %q", wireUserID.Domain, wireDeviceID.Domain)
- case wireUserID.Name != wireDeviceID.Name:
- return fmt.Errorf("UserID name %q does not match DeviceID name %q", wireUserID.Name, wireDeviceID.Name)
- case wireUserID.Handle != wireDeviceID.Handle:
- return fmt.Errorf("UserID handle %q does not match DeviceID handle %q", wireUserID.Handle, wireDeviceID.Handle)
- }
-
- return nil
-}
-
-// hasWireIdentifiers returns whether the [NewOrderRequest] contains
-// Wire identifiers.
-func (n *NewOrderRequest) hasWireIdentifiers() bool {
- for _, i := range n.Identifiers {
- if i.Type == acme.WireUser || i.Type == acme.WireDevice {
- return true
- }
- }
- return false
-}
-
-// identifiersOfType returns the Identifiers that are of type typ.
-func identifiersOfType(typ acme.IdentifierType, ids []acme.Identifier) (result []acme.Identifier) {
- for _, id := range ids {
- if id.Type == typ {
- result = append(result, id)
- }
- }
- return
-}
-
// FinalizeRequest captures the body for a Finalize order request.
type FinalizeRequest struct {
CSR string `json:"csr"`
@@ -171,29 +99,29 @@ func NewOrder(w http.ResponseWriter, r *http.Request) {
acc, err := accountFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
prov, err := provisionerFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
payload, err := payloadFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
var nor NewOrderRequest
if err := json.Unmarshal(payload.value, &nor); err != nil {
- render.Error(w, r, acme.WrapError(acme.ErrorMalformedType, err,
+ render.Error(w, acme.WrapError(acme.ErrorMalformedType, err,
"failed to unmarshal new-order request payload"))
return
}
if err := nor.Validate(); err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
@@ -202,39 +130,39 @@ func NewOrder(w http.ResponseWriter, r *http.Request) {
acmeProv, err := acmeProvisionerFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
var eak *acme.ExternalAccountKey
if acmeProv.RequireEAB {
if eak, err = db.GetExternalAccountKeyByAccountID(ctx, prov.GetID(), acc.ID); err != nil {
- render.Error(w, r, acme.WrapErrorISE(err, "error retrieving external account binding key"))
+ render.Error(w, acme.WrapErrorISE(err, "error retrieving external account binding key"))
return
}
}
acmePolicy, err := newACMEPolicyEngine(eak)
if err != nil {
- render.Error(w, r, acme.WrapErrorISE(err, "error creating ACME policy engine"))
+ render.Error(w, acme.WrapErrorISE(err, "error creating ACME policy engine"))
return
}
for _, identifier := range nor.Identifiers {
// evaluate the ACME account level policy
if err = isIdentifierAllowed(acmePolicy, identifier); err != nil {
- render.Error(w, r, acme.WrapError(acme.ErrorRejectedIdentifierType, err, "not authorized"))
+ render.Error(w, acme.WrapError(acme.ErrorRejectedIdentifierType, err, "not authorized"))
return
}
// evaluate the provisioner level policy
orderIdentifier := provisioner.ACMEIdentifier{Type: provisioner.ACMEIdentifierType(identifier.Type), Value: identifier.Value}
if err = prov.AuthorizeOrderIdentifier(ctx, orderIdentifier); err != nil {
- render.Error(w, r, acme.WrapError(acme.ErrorRejectedIdentifierType, err, "not authorized"))
+ render.Error(w, acme.WrapError(acme.ErrorRejectedIdentifierType, err, "not authorized"))
return
}
// evaluate the authority level policy
if err = ca.AreSANsAllowed(ctx, []string{identifier.Value}); err != nil {
- render.Error(w, r, acme.WrapError(acme.ErrorRejectedIdentifierType, err, "not authorized"))
+ render.Error(w, acme.WrapError(acme.ErrorRejectedIdentifierType, err, "not authorized"))
return
}
}
@@ -260,7 +188,7 @@ func NewOrder(w http.ResponseWriter, r *http.Request) {
Status: acme.StatusPending,
}
if err := newAuthorization(ctx, az); err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
o.AuthorizationIDs[i] = az.ID
@@ -279,14 +207,14 @@ func NewOrder(w http.ResponseWriter, r *http.Request) {
}
if err := db.CreateOrder(ctx, o); err != nil {
- render.Error(w, r, acme.WrapErrorISE(err, "error creating order"))
+ render.Error(w, acme.WrapErrorISE(err, "error creating order"))
return
}
linker.LinkOrder(ctx, o)
w.Header().Set("Location", linker.GetLink(ctx, acme.OrderLinkType, o.ID))
- render.JSONStatus(w, r, o, http.StatusCreated)
+ render.JSONStatus(w, o, http.StatusCreated)
}
func isIdentifierAllowed(acmePolicy policy.X509Policy, identifier acme.Identifier) error {
@@ -298,7 +226,6 @@ func isIdentifierAllowed(acmePolicy policy.X509Policy, identifier acme.Identifie
func newACMEPolicyEngine(eak *acme.ExternalAccountKey) (policy.X509Policy, error) {
if eak == nil {
- //nolint:nilnil,nolintlint // expected values
return nil, nil
}
return policy.NewX509PolicyEngine(eak.Policy)
@@ -335,43 +262,12 @@ func newAuthorization(ctx context.Context, az *acme.Authorization) error {
continue
}
- var target string
- switch az.Identifier.Type {
- case acme.WireUser:
- wireOptions, err := prov.GetOptions().GetWireOptions()
- if err != nil {
- return acme.WrapErrorISE(err, "failed getting Wire options")
- }
- target, err = wireOptions.GetOIDCOptions().EvaluateTarget("") // TODO(hs): determine if required by Wire
- if err != nil {
- return acme.WrapError(acme.ErrorMalformedType, err, "invalid Go template registered for 'target'")
- }
- case acme.WireDevice:
- wireID, err := wire.ParseDeviceID(az.Identifier.Value)
- if err != nil {
- return acme.WrapError(acme.ErrorMalformedType, err, "failed parsing WireDevice")
- }
- clientID, err := wire.ParseClientID(wireID.ClientID)
- if err != nil {
- return acme.WrapError(acme.ErrorMalformedType, err, "failed parsing ClientID")
- }
- wireOptions, err := prov.GetOptions().GetWireOptions()
- if err != nil {
- return acme.WrapErrorISE(err, "failed getting Wire options")
- }
- target, err = wireOptions.GetDPOPOptions().EvaluateTarget(clientID.DeviceID)
- if err != nil {
- return acme.WrapError(acme.ErrorMalformedType, err, "invalid Go template registered for 'target'")
- }
- }
-
ch := &acme.Challenge{
AccountID: az.AccountID,
Value: az.Identifier.Value,
Type: typ,
Token: az.Token,
Status: acme.StatusPending,
- Target: target,
}
if err := db.CreateChallenge(ctx, ch); err != nil {
return acme.WrapErrorISE(err, "error creating challenge")
@@ -392,39 +288,39 @@ func GetOrder(w http.ResponseWriter, r *http.Request) {
acc, err := accountFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
prov, err := provisionerFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
o, err := db.GetOrder(ctx, chi.URLParam(r, "ordID"))
if err != nil {
- render.Error(w, r, acme.WrapErrorISE(err, "error retrieving order"))
+ render.Error(w, acme.WrapErrorISE(err, "error retrieving order"))
return
}
if acc.ID != o.AccountID {
- render.Error(w, r, acme.NewError(acme.ErrorUnauthorizedType,
+ render.Error(w, acme.NewError(acme.ErrorUnauthorizedType,
"account '%s' does not own order '%s'", acc.ID, o.ID))
return
}
if prov.GetID() != o.ProvisionerID {
- render.Error(w, r, acme.NewError(acme.ErrorUnauthorizedType,
+ render.Error(w, acme.NewError(acme.ErrorUnauthorizedType,
"provisioner '%s' does not own order '%s'", prov.GetID(), o.ID))
return
}
if err = o.UpdateStatus(ctx, db); err != nil {
- render.Error(w, r, acme.WrapErrorISE(err, "error updating order status"))
+ render.Error(w, acme.WrapErrorISE(err, "error updating order status"))
return
}
linker.LinkOrder(ctx, o)
w.Header().Set("Location", linker.GetLink(ctx, acme.OrderLinkType, o.ID))
- render.JSON(w, r, o)
+ render.JSON(w, o)
}
// FinalizeOrder attempts to finalize an order and create a certificate.
@@ -435,56 +331,56 @@ func FinalizeOrder(w http.ResponseWriter, r *http.Request) {
acc, err := accountFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
prov, err := provisionerFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
payload, err := payloadFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
var fr FinalizeRequest
if err := json.Unmarshal(payload.value, &fr); err != nil {
- render.Error(w, r, acme.WrapError(acme.ErrorMalformedType, err,
+ render.Error(w, acme.WrapError(acme.ErrorMalformedType, err,
"failed to unmarshal finalize-order request payload"))
return
}
if err := fr.Validate(); err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
o, err := db.GetOrder(ctx, chi.URLParam(r, "ordID"))
if err != nil {
- render.Error(w, r, acme.WrapErrorISE(err, "error retrieving order"))
+ render.Error(w, acme.WrapErrorISE(err, "error retrieving order"))
return
}
if acc.ID != o.AccountID {
- render.Error(w, r, acme.NewError(acme.ErrorUnauthorizedType,
+ render.Error(w, acme.NewError(acme.ErrorUnauthorizedType,
"account '%s' does not own order '%s'", acc.ID, o.ID))
return
}
if prov.GetID() != o.ProvisionerID {
- render.Error(w, r, acme.NewError(acme.ErrorUnauthorizedType,
+ render.Error(w, acme.NewError(acme.ErrorUnauthorizedType,
"provisioner '%s' does not own order '%s'", prov.GetID(), o.ID))
return
}
ca := mustAuthority(ctx)
if err = o.Finalize(ctx, db, fr.csr, ca, prov); err != nil {
- render.Error(w, r, acme.WrapErrorISE(err, "error finalizing order"))
+ render.Error(w, acme.WrapErrorISE(err, "error finalizing order"))
return
}
linker.LinkOrder(ctx, o)
w.Header().Set("Location", linker.GetLink(ctx, acme.OrderLinkType, o.ID))
- render.JSON(w, r, o)
+ render.JSON(w, o)
}
// challengeTypes determines the types of challenges that should be used
@@ -503,10 +399,6 @@ func challengeTypes(az *acme.Authorization) []acme.ChallengeType {
}
case acme.PermanentIdentifier:
chTypes = []acme.ChallengeType{acme.DEVICEATTEST01}
- case acme.WireUser:
- chTypes = []acme.ChallengeType{acme.WIREOIDC01}
- case acme.WireDevice:
- chTypes = []acme.ChallengeType{acme.WIREDPOP01}
default:
chTypes = []acme.ChallengeType{}
}
diff --git a/vendor/github.com/smallstep/certificates/acme/api/revoke.go b/vendor/github.com/smallstep/certificates/acme/api/revoke.go
index c613df2..270a9fb 100644
--- a/vendor/github.com/smallstep/certificates/acme/api/revoke.go
+++ b/vendor/github.com/smallstep/certificates/acme/api/revoke.go
@@ -33,65 +33,65 @@ func RevokeCert(w http.ResponseWriter, r *http.Request) {
jws, err := jwsFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
prov, err := provisionerFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
payload, err := payloadFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
var p revokePayload
err = json.Unmarshal(payload.value, &p)
if err != nil {
- render.Error(w, r, acme.WrapErrorISE(err, "error unmarshaling payload"))
+ render.Error(w, acme.WrapErrorISE(err, "error unmarshaling payload"))
return
}
certBytes, err := base64.RawURLEncoding.DecodeString(p.Certificate)
if err != nil {
// in this case the most likely cause is a client that didn't properly encode the certificate
- render.Error(w, r, acme.WrapError(acme.ErrorMalformedType, err, "error base64url decoding payload certificate property"))
+ render.Error(w, acme.WrapError(acme.ErrorMalformedType, err, "error base64url decoding payload certificate property"))
return
}
certToBeRevoked, err := x509.ParseCertificate(certBytes)
if err != nil {
// in this case a client may have encoded something different than a certificate
- render.Error(w, r, acme.WrapError(acme.ErrorMalformedType, err, "error parsing certificate"))
+ render.Error(w, acme.WrapError(acme.ErrorMalformedType, err, "error parsing certificate"))
return
}
serial := certToBeRevoked.SerialNumber.String()
dbCert, err := db.GetCertificateBySerial(ctx, serial)
if err != nil {
- render.Error(w, r, acme.WrapErrorISE(err, "error retrieving certificate by serial"))
+ render.Error(w, acme.WrapErrorISE(err, "error retrieving certificate by serial"))
return
}
if !bytes.Equal(dbCert.Leaf.Raw, certToBeRevoked.Raw) {
// this should never happen
- render.Error(w, r, acme.NewErrorISE("certificate raw bytes are not equal"))
+ render.Error(w, acme.NewErrorISE("certificate raw bytes are not equal"))
return
}
if shouldCheckAccountFrom(jws) {
account, err := accountFromContext(ctx)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
acmeErr := isAccountAuthorized(ctx, dbCert, certToBeRevoked, account)
if acmeErr != nil {
- render.Error(w, r, acmeErr)
+ render.Error(w, acmeErr)
return
}
} else {
@@ -100,7 +100,7 @@ func RevokeCert(w http.ResponseWriter, r *http.Request) {
_, err := jws.Verify(certToBeRevoked.PublicKey)
if err != nil {
// TODO(hs): possible to determine an error vs. unauthorized and thus provide an ISE vs. Unauthorized?
- render.Error(w, r, wrapUnauthorizedError(certToBeRevoked, nil, "verification of jws using certificate public key failed", err))
+ render.Error(w, wrapUnauthorizedError(certToBeRevoked, nil, "verification of jws using certificate public key failed", err))
return
}
}
@@ -108,19 +108,19 @@ func RevokeCert(w http.ResponseWriter, r *http.Request) {
ca := mustAuthority(ctx)
hasBeenRevokedBefore, err := ca.IsRevoked(serial)
if err != nil {
- render.Error(w, r, acme.WrapErrorISE(err, "error retrieving revocation status of certificate"))
+ render.Error(w, acme.WrapErrorISE(err, "error retrieving revocation status of certificate"))
return
}
if hasBeenRevokedBefore {
- render.Error(w, r, acme.NewError(acme.ErrorAlreadyRevokedType, "certificate was already revoked"))
+ render.Error(w, acme.NewError(acme.ErrorAlreadyRevokedType, "certificate was already revoked"))
return
}
reasonCode := p.ReasonCode
acmeErr := validateReasonCode(reasonCode)
if acmeErr != nil {
- render.Error(w, r, acmeErr)
+ render.Error(w, acmeErr)
return
}
@@ -128,14 +128,14 @@ func RevokeCert(w http.ResponseWriter, r *http.Request) {
ctx = provisioner.NewContextWithMethod(ctx, provisioner.RevokeMethod)
err = prov.AuthorizeRevoke(ctx, "")
if err != nil {
- render.Error(w, r, acme.WrapErrorISE(err, "error authorizing revocation on provisioner"))
+ render.Error(w, acme.WrapErrorISE(err, "error authorizing revocation on provisioner"))
return
}
options := revokeOptions(serial, certToBeRevoked, reasonCode)
err = ca.Revoke(ctx, options)
if err != nil {
- render.Error(w, r, wrapRevokeErr(err))
+ render.Error(w, wrapRevokeErr(err))
return
}
@@ -180,7 +180,7 @@ func isAccountAuthorized(_ context.Context, dbCert *acme.Certificate, certToBeRe
func wrapRevokeErr(err error) *acme.Error {
t := err.Error()
if strings.Contains(t, "is already revoked") {
- return acme.NewError(acme.ErrorAlreadyRevokedType, t) //nolint:govet // allow non-constant error messages
+ return acme.NewError(acme.ErrorAlreadyRevokedType, t)
}
return acme.WrapErrorISE(err, "error when revoking certificate")
}
@@ -190,9 +190,9 @@ func wrapRevokeErr(err error) *acme.Error {
func wrapUnauthorizedError(cert *x509.Certificate, unauthorizedIdentifiers []acme.Identifier, msg string, err error) *acme.Error {
var acmeErr *acme.Error
if err == nil {
- acmeErr = acme.NewError(acme.ErrorUnauthorizedType, msg) //nolint:govet // allow non-constant error messages
+ acmeErr = acme.NewError(acme.ErrorUnauthorizedType, msg)
} else {
- acmeErr = acme.WrapError(acme.ErrorUnauthorizedType, err, msg) //nolint:govet // allow non-constant error messages
+ acmeErr = acme.WrapError(acme.ErrorUnauthorizedType, err, msg)
}
acmeErr.Status = http.StatusForbidden // RFC8555 7.6 shows example with 403
diff --git a/vendor/github.com/smallstep/certificates/acme/challenge.go b/vendor/github.com/smallstep/certificates/acme/challenge.go
index cf658cf..9f3ca38 100644
--- a/vendor/github.com/smallstep/certificates/acme/challenge.go
+++ b/vendor/github.com/smallstep/certificates/acme/challenge.go
@@ -1,7 +1,6 @@
package acme
import (
- "bytes"
"context"
"crypto"
"crypto/ecdsa"
@@ -26,19 +25,18 @@ import (
"strings"
"time"
- "github.com/coreos/go-oidc/v3/oidc"
"github.com/fxamacker/cbor/v2"
"github.com/google/go-tpm/legacy/tpm2"
+ "golang.org/x/exp/slices"
+
"github.com/smallstep/go-attestation/attest"
+
"go.step.sm/crypto/jose"
"go.step.sm/crypto/keyutil"
"go.step.sm/crypto/pemutil"
"go.step.sm/crypto/x509util"
- "golang.org/x/exp/slices"
- "github.com/smallstep/certificates/acme/wire"
"github.com/smallstep/certificates/authority/provisioner"
- wireprovisioner "github.com/smallstep/certificates/authority/provisioner/wire"
)
type ChallengeType string
@@ -52,10 +50,6 @@ const (
TLSALPN01 ChallengeType = "tls-alpn-01"
// DEVICEATTEST01 is the device-attest-01 ACME challenge type
DEVICEATTEST01 ChallengeType = "device-attest-01"
- // WIREOIDC01 is the Wire OIDC challenge type
- WIREOIDC01 ChallengeType = "wire-oidc-01"
- // WIREDPOP01 is the Wire DPoP challenge type
- WIREDPOP01 ChallengeType = "wire-dpop-01"
)
var (
@@ -68,11 +62,6 @@ var (
//
// This variable can be used for testing purposes.
InsecurePortTLSALPN01 int
-
- // StrictFQDN allows to enforce a fully qualified domain name in the DNS
- // resolution. By default it allows domain resolution using a search list
- // defined in the resolv.conf or similar configuration.
- StrictFQDN bool
)
// Challenge represents an ACME response Challenge type.
@@ -86,7 +75,6 @@ type Challenge struct {
Token string `json:"token"`
ValidatedAt string `json:"validated,omitempty"`
URL string `json:"url"`
- Target string `json:"target,omitempty"`
Error *Error `json:"error,omitempty"`
}
@@ -116,37 +104,22 @@ func (ch *Challenge) Validate(ctx context.Context, db DB, jwk *jose.JSONWebKey,
return tlsalpn01Validate(ctx, ch, db, jwk)
case DEVICEATTEST01:
return deviceAttest01Validate(ctx, ch, db, jwk, payload)
- case WIREOIDC01:
- wireDB, ok := db.(WireDB)
- if !ok {
- return NewErrorISE("db %T is not a WireDB", db)
- }
- return wireOIDC01Validate(ctx, ch, wireDB, jwk, payload)
- case WIREDPOP01:
- wireDB, ok := db.(WireDB)
- if !ok {
- return NewErrorISE("db %T is not a WireDB", db)
- }
- return wireDPOP01Validate(ctx, ch, wireDB, jwk, payload)
default:
- return NewErrorISE("unexpected challenge type %q", ch.Type)
+ return NewErrorISE("unexpected challenge type '%s'", ch.Type)
}
}
func http01Validate(ctx context.Context, ch *Challenge, db DB, jwk *jose.JSONWebKey) error {
- u := &url.URL{Scheme: "http", Host: ch.Value, Path: fmt.Sprintf("/.well-known/acme-challenge/%s", ch.Token)}
- challengeURL := &url.URL{Scheme: "http", Host: http01ChallengeHost(ch.Value), Path: fmt.Sprintf("/.well-known/acme-challenge/%s", ch.Token)}
+ u := &url.URL{Scheme: "http", Host: http01ChallengeHost(ch.Value), Path: fmt.Sprintf("/.well-known/acme-challenge/%s", ch.Token)}
// Append insecure port if set.
// Only used for testing purposes.
if InsecurePortHTTP01 != 0 {
- insecurePort := strconv.Itoa(InsecurePortHTTP01)
- u.Host += ":" + insecurePort
- challengeURL.Host += ":" + insecurePort
+ u.Host += ":" + strconv.Itoa(InsecurePortHTTP01)
}
vc := MustClientFromContext(ctx)
- resp, err := vc.Get(challengeURL.String())
+ resp, err := vc.Get(u.String())
if err != nil {
return storeError(ctx, db, ch, false, WrapError(ErrorConnectionType, err,
"error doing http GET for url %s", u))
@@ -184,42 +157,15 @@ func http01Validate(ctx context.Context, ch *Challenge, db DB, jwk *jose.JSONWeb
return nil
}
-// rootedName adds a trailing "." to a given domain name.
-func rootedName(name string) string {
- if StrictFQDN {
- if name == "" || name[len(name)-1] != '.' {
- return name + "."
- }
- }
- return name
-}
-
// http01ChallengeHost checks if a Challenge value is an IPv6 address
// and adds square brackets if that's the case, so that it can be used
// as a hostname. Returns the original Challenge value as the host to
// use in other cases.
func http01ChallengeHost(value string) string {
- if ip := net.ParseIP(value); ip != nil {
- if ip.To4() == nil {
- value = "[" + value + "]"
- }
- return value
- }
- return rootedName(value)
-}
-
-// tlsAlpn01ChallengeHost returns the rooted DNS used on TLS-ALPN-01
-// validations.
-func tlsAlpn01ChallengeHost(name string) string {
- if ip := net.ParseIP(name); ip != nil {
- return name
+ if ip := net.ParseIP(value); ip != nil && ip.To4() == nil {
+ value = "[" + value + "]"
}
- return rootedName(name)
-}
-
-// dns01ChallengeHost returns the TXT record used in DNS-01 validations.
-func dns01ChallengeHost(domain string) string {
- return "_acme-challenge." + rootedName(domain)
+ return value
}
func tlsAlert(err error) uint8 {
@@ -244,12 +190,13 @@ func tlsalpn01Validate(ctx context.Context, ch *Challenge, db DB, jwk *jose.JSON
InsecureSkipVerify: true, //nolint:gosec // we expect a self-signed challenge certificate
}
+ var hostPort string
+
// Allow to change TLS port for testing purposes.
- hostPort := tlsAlpn01ChallengeHost(ch.Value)
if port := InsecurePortTLSALPN01; port == 0 {
- hostPort = net.JoinHostPort(hostPort, "443")
+ hostPort = net.JoinHostPort(ch.Value, "443")
} else {
- hostPort = net.JoinHostPort(hostPort, strconv.Itoa(port))
+ hostPort = net.JoinHostPort(ch.Value, strconv.Itoa(port))
}
vc := MustClientFromContext(ctx)
@@ -264,7 +211,7 @@ func tlsalpn01Validate(ctx context.Context, ch *Challenge, db DB, jwk *jose.JSON
"cannot negotiate ALPN acme-tls/1 protocol for tls-alpn-01 challenge"))
}
return storeError(ctx, db, ch, false, WrapError(ErrorConnectionType, err,
- "error doing TLS dial for %s", ch.Value))
+ "error doing TLS dial for %s", hostPort))
}
defer conn.Close()
@@ -360,7 +307,7 @@ func dns01Validate(ctx context.Context, ch *Challenge, db DB, jwk *jose.JSONWebK
domain := strings.TrimPrefix(ch.Value, "*.")
vc := MustClientFromContext(ctx)
- txtRecords, err := vc.LookupTxt(dns01ChallengeHost(domain))
+ txtRecords, err := vc.LookupTxt("_acme-challenge." + domain)
if err != nil {
return storeError(ctx, db, ch, false, WrapError(ErrorDNSType, err,
"error looking up TXT records for domain %s", domain))
@@ -395,387 +342,6 @@ func dns01Validate(ctx context.Context, ch *Challenge, db DB, jwk *jose.JSONWebK
return nil
}
-type wireOidcPayload struct {
- // IDToken contains the OIDC identity token
- IDToken string `json:"id_token"`
-}
-
-func wireOIDC01Validate(ctx context.Context, ch *Challenge, db WireDB, jwk *jose.JSONWebKey, payload []byte) error {
- prov, ok := ProvisionerFromContext(ctx)
- if !ok {
- return NewErrorISE("missing provisioner")
- }
- wireOptions, err := prov.GetOptions().GetWireOptions()
- if err != nil {
- return WrapErrorISE(err, "failed getting Wire options")
- }
- linker, ok := LinkerFromContext(ctx)
- if !ok {
- return NewErrorISE("missing linker")
- }
-
- var oidcPayload wireOidcPayload
- if err := json.Unmarshal(payload, &oidcPayload); err != nil {
- return WrapError(ErrorMalformedType, err, "error unmarshalling Wire OIDC challenge payload")
- }
-
- wireID, err := wire.ParseUserID(ch.Value)
- if err != nil {
- return WrapErrorISE(err, "error unmarshalling challenge data")
- }
-
- oidcOptions := wireOptions.GetOIDCOptions()
- verifier, err := oidcOptions.GetVerifier(ctx)
- if err != nil {
- return WrapErrorISE(err, "no OIDC verifier available")
- }
-
- idToken, err := verifier.Verify(ctx, oidcPayload.IDToken)
- if err != nil {
- return storeError(ctx, db, ch, true, WrapError(ErrorRejectedIdentifierType, err,
- "error verifying ID token signature"))
- }
-
- var claims struct {
- Name string `json:"preferred_username,omitempty"`
- Handle string `json:"name"`
- Issuer string `json:"iss,omitempty"`
- GivenName string `json:"given_name,omitempty"`
- KeyAuth string `json:"keyauth"`
- ACMEAudience string `json:"acme_aud,omitempty"`
- }
- if err := idToken.Claims(&claims); err != nil {
- return storeError(ctx, db, ch, true, WrapError(ErrorRejectedIdentifierType, err,
- "error retrieving claims from ID token"))
- }
-
- // TODO(hs): move this into validation below?
- expectedKeyAuth, err := KeyAuthorization(ch.Token, jwk)
- if err != nil {
- return WrapErrorISE(err, "error determining key authorization")
- }
- if expectedKeyAuth != claims.KeyAuth {
- return storeError(ctx, db, ch, true, NewError(ErrorRejectedIdentifierType,
- "keyAuthorization does not match; expected %q, but got %q", expectedKeyAuth, claims.KeyAuth))
- }
-
- // audience is the full URL to the challenge
- acmeAudience := linker.GetLink(ctx, ChallengeLinkType, ch.AuthorizationID, ch.ID)
- if claims.ACMEAudience != acmeAudience {
- return storeError(ctx, db, ch, true, NewError(ErrorRejectedIdentifierType,
- "invalid 'acme_aud' %q", claims.ACMEAudience))
- }
-
- transformedIDToken, err := validateWireOIDCClaims(oidcOptions, idToken, wireID)
- if err != nil {
- return storeError(ctx, db, ch, true, WrapError(ErrorRejectedIdentifierType, err, "claims in OIDC ID token don't match"))
- }
-
- // Update and store the challenge.
- ch.Status = StatusValid
- ch.Error = nil
- ch.ValidatedAt = clock.Now().Format(time.RFC3339)
-
- if err = db.UpdateChallenge(ctx, ch); err != nil {
- return WrapErrorISE(err, "error updating challenge")
- }
-
- orders, err := db.GetAllOrdersByAccountID(ctx, ch.AccountID)
- if err != nil {
- return WrapErrorISE(err, "could not retrieve current order by account id")
- }
- if len(orders) == 0 {
- return NewErrorISE("there are not enough orders for this account for this custom OIDC challenge")
- }
-
- order := orders[len(orders)-1]
- if err := db.CreateOidcToken(ctx, order, transformedIDToken); err != nil {
- return WrapErrorISE(err, "failed storing OIDC id token")
- }
-
- return nil
-}
-
-func validateWireOIDCClaims(o *wireprovisioner.OIDCOptions, token *oidc.IDToken, wireID wire.UserID) (map[string]any, error) {
- var m map[string]any
- if err := token.Claims(&m); err != nil {
- return nil, fmt.Errorf("failed extracting OIDC ID token claims: %w", err)
- }
- transformed, err := o.Transform(m)
- if err != nil {
- return nil, fmt.Errorf("failed transforming OIDC ID token: %w", err)
- }
-
- name, ok := transformed["name"]
- if !ok {
- return nil, fmt.Errorf("transformed OIDC ID token does not contain 'name'")
- }
- if wireID.Name != name {
- return nil, fmt.Errorf("invalid 'name' %q after transformation", name)
- }
-
- preferredUsername, ok := transformed["preferred_username"]
- if !ok {
- return nil, fmt.Errorf("transformed OIDC ID token does not contain 'preferred_username'")
- }
- if wireID.Handle != preferredUsername {
- return nil, fmt.Errorf("invalid 'preferred_username' %q after transformation", preferredUsername)
- }
-
- return transformed, nil
-}
-
-type wireDpopPayload struct {
- // AccessToken is the token generated by wire-server
- AccessToken string `json:"access_token"`
-}
-
-func wireDPOP01Validate(ctx context.Context, ch *Challenge, db WireDB, accountJWK *jose.JSONWebKey, payload []byte) error {
- prov, ok := ProvisionerFromContext(ctx)
- if !ok {
- return NewErrorISE("missing provisioner")
- }
- wireOptions, err := prov.GetOptions().GetWireOptions()
- if err != nil {
- return WrapErrorISE(err, "failed getting Wire options")
- }
- linker, ok := LinkerFromContext(ctx)
- if !ok {
- return NewErrorISE("missing linker")
- }
-
- var dpopPayload wireDpopPayload
- if err := json.Unmarshal(payload, &dpopPayload); err != nil {
- return WrapError(ErrorMalformedType, err, "error unmarshalling Wire DPoP challenge payload")
- }
-
- wireID, err := wire.ParseDeviceID(ch.Value)
- if err != nil {
- return WrapErrorISE(err, "error unmarshalling challenge data")
- }
-
- clientID, err := wire.ParseClientID(wireID.ClientID)
- if err != nil {
- return WrapErrorISE(err, "error parsing device id")
- }
-
- dpopOptions := wireOptions.GetDPOPOptions()
- issuer, err := dpopOptions.EvaluateTarget(clientID.DeviceID)
- if err != nil {
- return WrapErrorISE(err, "invalid Go template registered for 'target'")
- }
-
- // audience is the full URL to the challenge
- audience := linker.GetLink(ctx, ChallengeLinkType, ch.AuthorizationID, ch.ID)
-
- params := wireVerifyParams{
- token: dpopPayload.AccessToken,
- tokenKey: dpopOptions.GetSigningKey(),
- dpopKey: accountJWK.Public(),
- dpopKeyID: accountJWK.KeyID,
- issuer: issuer,
- audience: audience,
- wireID: wireID,
- chToken: ch.Token,
- t: clock.Now().UTC(),
- }
- _, dpop, err := parseAndVerifyWireAccessToken(params)
- if err != nil {
- return storeError(ctx, db, ch, true, WrapError(ErrorRejectedIdentifierType, err,
- "failed validating Wire access token"))
- }
-
- // Update and store the challenge.
- ch.Status = StatusValid
- ch.Error = nil
- ch.ValidatedAt = clock.Now().Format(time.RFC3339)
-
- if err = db.UpdateChallenge(ctx, ch); err != nil {
- return WrapErrorISE(err, "error updating challenge")
- }
-
- orders, err := db.GetAllOrdersByAccountID(ctx, ch.AccountID)
- if err != nil {
- return WrapErrorISE(err, "could not find current order by account id")
- }
- if len(orders) == 0 {
- return NewErrorISE("there are not enough orders for this account for this custom OIDC challenge")
- }
-
- order := orders[len(orders)-1]
- if err := db.CreateDpopToken(ctx, order, map[string]any(*dpop)); err != nil {
- return WrapErrorISE(err, "failed storing DPoP token")
- }
-
- return nil
-}
-
-type wireCnf struct {
- Kid string `json:"kid"`
-}
-
-type wireAccessToken struct {
- jose.Claims
- Challenge string `json:"chal"`
- Nonce string `json:"nonce"`
- Cnf wireCnf `json:"cnf"`
- Proof string `json:"proof"`
- ClientID string `json:"client_id"`
- APIVersion int `json:"api_version"`
- Scope string `json:"scope"`
-}
-
-type wireDpopJwt struct {
- jose.Claims
- ClientID string `json:"client_id"`
- Challenge string `json:"chal"`
- Nonce string `json:"nonce"`
- HTU string `json:"htu"`
-}
-
-type wireDpopToken map[string]any
-
-type wireVerifyParams struct {
- token string
- tokenKey crypto.PublicKey
- dpopKey crypto.PublicKey
- dpopKeyID string
- issuer string
- audience string
- wireID wire.DeviceID
- chToken string
- t time.Time
-}
-
-func parseAndVerifyWireAccessToken(v wireVerifyParams) (*wireAccessToken, *wireDpopToken, error) {
- jwt, err := jose.ParseSigned(v.token)
- if err != nil {
- return nil, nil, fmt.Errorf("failed parsing token: %w", err)
- }
-
- if len(jwt.Headers) != 1 {
- return nil, nil, fmt.Errorf("token has wrong number of headers %d", len(jwt.Headers))
- }
- keyID, err := KeyToID(&jose.JSONWebKey{Key: v.tokenKey})
- if err != nil {
- return nil, nil, fmt.Errorf("failed calculating token key ID: %w", err)
- }
- jwtKeyID := jwt.Headers[0].KeyID
- if jwtKeyID == "" {
- if jwtKeyID, err = KeyToID(jwt.Headers[0].JSONWebKey); err != nil {
- return nil, nil, fmt.Errorf("failed extracting token key ID: %w", err)
- }
- }
- if jwtKeyID != keyID {
- return nil, nil, fmt.Errorf("invalid token key ID %q", jwtKeyID)
- }
-
- var accessToken wireAccessToken
- if err = jwt.Claims(v.tokenKey, &accessToken); err != nil {
- return nil, nil, fmt.Errorf("failed validating Wire DPoP token claims: %w", err)
- }
-
- if err := accessToken.ValidateWithLeeway(jose.Expected{
- Time: v.t,
- Issuer: v.issuer,
- Audience: jose.Audience{v.audience},
- }, 1*time.Minute); err != nil {
- return nil, nil, fmt.Errorf("failed validation: %w", err)
- }
-
- if accessToken.Challenge == "" {
- return nil, nil, errors.New("access token challenge 'chal' must not be empty")
- }
- if accessToken.Cnf.Kid == "" || accessToken.Cnf.Kid != v.dpopKeyID {
- return nil, nil, fmt.Errorf("expected 'kid' %q; got %q", v.dpopKeyID, accessToken.Cnf.Kid)
- }
- if accessToken.ClientID != v.wireID.ClientID {
- return nil, nil, fmt.Errorf("invalid Wire 'client_id' %q", accessToken.ClientID)
- }
- if accessToken.Expiry.Time().After(v.t.Add(time.Hour)) {
- return nil, nil, fmt.Errorf("token expiry 'exp' %s is too far into the future", accessToken.Expiry.Time().String())
- }
- if accessToken.Scope != "wire_client_id" {
- return nil, nil, fmt.Errorf("invalid Wire 'scope' %q", accessToken.Scope)
- }
-
- dpopJWT, err := jose.ParseSigned(accessToken.Proof)
- if err != nil {
- return nil, nil, fmt.Errorf("invalid Wire DPoP token: %w", err)
- }
- if len(dpopJWT.Headers) != 1 {
- return nil, nil, fmt.Errorf("DPoP token has wrong number of headers %d", len(jwt.Headers))
- }
- dpopJwtKeyID := dpopJWT.Headers[0].KeyID
- if dpopJwtKeyID == "" {
- if dpopJwtKeyID, err = KeyToID(dpopJWT.Headers[0].JSONWebKey); err != nil {
- return nil, nil, fmt.Errorf("failed extracting DPoP token key ID: %w", err)
- }
- }
- if dpopJwtKeyID != v.dpopKeyID {
- return nil, nil, fmt.Errorf("invalid DPoP token key ID %q", dpopJWT.Headers[0].KeyID)
- }
-
- var wireDpop wireDpopJwt
- if err := dpopJWT.Claims(v.dpopKey, &wireDpop); err != nil {
- return nil, nil, fmt.Errorf("failed validating Wire DPoP token claims: %w", err)
- }
-
- if err := wireDpop.ValidateWithLeeway(jose.Expected{
- Time: v.t,
- Audience: jose.Audience{v.audience},
- }, 1*time.Minute); err != nil {
- return nil, nil, fmt.Errorf("failed DPoP validation: %w", err)
- }
- if wireDpop.HTU == "" || wireDpop.HTU != v.issuer { // DPoP doesn't contains "iss" claim, but has it in the "htu" claim
- return nil, nil, fmt.Errorf("DPoP contains invalid issuer 'htu' %q", wireDpop.HTU)
- }
- if wireDpop.Expiry.Time().After(v.t.Add(time.Hour)) {
- return nil, nil, fmt.Errorf("'exp' %s is too far into the future", wireDpop.Expiry.Time().String())
- }
- if wireDpop.Subject != v.wireID.ClientID {
- return nil, nil, fmt.Errorf("DPoP contains invalid Wire client ID %q", wireDpop.ClientID)
- }
- if wireDpop.Nonce == "" || wireDpop.Nonce != accessToken.Nonce {
- return nil, nil, fmt.Errorf("DPoP contains invalid 'nonce' %q", wireDpop.Nonce)
- }
- if wireDpop.Challenge == "" || wireDpop.Challenge != accessToken.Challenge {
- return nil, nil, fmt.Errorf("DPoP contains invalid challenge 'chal' %q", wireDpop.Challenge)
- }
-
- // TODO(hs): can we use the wireDpopJwt and map that instead of doing Claims() twice?
- var dpopToken wireDpopToken
- if err := dpopJWT.Claims(v.dpopKey, &dpopToken); err != nil {
- return nil, nil, fmt.Errorf("failed validating Wire DPoP token claims: %w", err)
- }
-
- challenge, ok := dpopToken["chal"].(string)
- if !ok {
- return nil, nil, fmt.Errorf("invalid challenge 'chal' in Wire DPoP token")
- }
- if challenge == "" || challenge != v.chToken {
- return nil, nil, fmt.Errorf("invalid Wire DPoP challenge 'chal' %q", challenge)
- }
-
- handle, ok := dpopToken["handle"].(string)
- if !ok {
- return nil, nil, fmt.Errorf("invalid 'handle' in Wire DPoP token")
- }
- if handle == "" || handle != v.wireID.Handle {
- return nil, nil, fmt.Errorf("invalid Wire client 'handle' %q", handle)
- }
-
- name, ok := dpopToken["name"].(string)
- if !ok {
- return nil, nil, fmt.Errorf("invalid display 'name' in Wire DPoP token")
- }
- if name == "" || name != v.wireID.Name {
- return nil, nil, fmt.Errorf("invalid Wire client display 'name' %q", name)
- }
-
- return &accessToken, &dpopToken, nil
-}
-
type payloadType struct {
AttObj string `json:"attObj"`
Error string `json:"error"`
@@ -806,26 +372,12 @@ func deviceAttest01Validate(ctx context.Context, ch *Challenge, db DB, jwk *jose
attObj, err := base64.RawURLEncoding.DecodeString(p.AttObj)
if err != nil {
- return storeError(ctx, db, ch, true, NewDetailedError(ErrorBadAttestationStatementType, "failed base64 decoding attObj %q", p.AttObj))
- }
-
- if len(attObj) == 0 || bytes.Equal(attObj, []byte("{}")) {
- return storeError(ctx, db, ch, true, NewDetailedError(ErrorBadAttestationStatementType, "attObj must not be empty"))
- }
-
- cborDecoderOptions := cbor.DecOptions{}
- cborDecoder, err := cborDecoderOptions.DecMode()
- if err != nil {
- return WrapErrorISE(err, "failed creating CBOR decoder")
- }
-
- if err := cborDecoder.Wellformed(attObj); err != nil {
- return storeError(ctx, db, ch, true, NewDetailedError(ErrorBadAttestationStatementType, "attObj is not well formed CBOR: %v", err))
+ return WrapErrorISE(err, "error base64 decoding attObj")
}
att := attestationObject{}
- if err := cborDecoder.Unmarshal(attObj, &att); err != nil {
- return WrapErrorISE(err, "failed unmarshalling CBOR")
+ if err := cbor.Unmarshal(attObj, &att); err != nil {
+ return WrapErrorISE(err, "error unmarshalling CBOR")
}
format := att.Format
@@ -1506,10 +1058,14 @@ func doStepAttestationFormat(_ context.Context, prov Provisioner, ch *Challenge,
// should be the ARPA address https://datatracker.ietf.org/doc/html/rfc8738#section-6.
// It also references TLS Extensions [RFC6066].
func serverName(ch *Challenge) string {
- if ip := net.ParseIP(ch.Value); ip != nil {
- return reverseAddr(ip)
+ var serverName string
+ ip := net.ParseIP(ch.Value)
+ if ip != nil {
+ serverName = reverseAddr(ip)
+ } else {
+ serverName = ch.Value
}
- return ch.Value
+ return serverName
}
// reverseaddr returns the in-addr.arpa. or ip6.arpa. hostname of the IP
diff --git a/vendor/github.com/smallstep/certificates/acme/db.go b/vendor/github.com/smallstep/certificates/acme/db.go
index bcbed41..4cbb308 100644
--- a/vendor/github.com/smallstep/certificates/acme/db.go
+++ b/vendor/github.com/smallstep/certificates/acme/db.go
@@ -2,7 +2,6 @@ package acme
import (
"context"
- "database/sql"
"github.com/pkg/errors"
)
@@ -16,7 +15,7 @@ var ErrNotFound = errors.New("not found")
// IsErrNotFound returns true if the error is a "not found" error. Returns false
// otherwise.
func IsErrNotFound(err error) bool {
- return errors.Is(err, ErrNotFound) || errors.Is(err, sql.ErrNoRows)
+ return errors.Is(err, ErrNotFound)
}
// DB is the DB interface expected by the step-ca ACME API.
@@ -56,19 +55,6 @@ type DB interface {
UpdateOrder(ctx context.Context, o *Order) error
}
-// WireDB is the interface used for operations on ACME Orders for Wire identifiers. This
-// is not a general purpose interface, and it should only be used when Wire identifiers
-// are enabled in the CA configuration. Currently it provides a runtime assertion only;
-// not at compile time.
-type WireDB interface {
- DB
- GetAllOrdersByAccountID(ctx context.Context, accountID string) ([]string, error)
- CreateDpopToken(ctx context.Context, orderID string, dpop map[string]interface{}) error
- GetDpopToken(ctx context.Context, orderID string) (map[string]interface{}, error)
- CreateOidcToken(ctx context.Context, orderID string, idToken map[string]interface{}) error
- GetOidcToken(ctx context.Context, orderID string) (map[string]interface{}, error)
-}
-
type dbKey struct{}
// NewDatabaseContext adds the given acme database to the context.
@@ -136,18 +122,6 @@ type MockDB struct {
MockError error
}
-// MockWireDB is an implementation of the WireDB interface that should only be used as
-// a mock in tests. It embeds the MockDB, as it is an extension of the existing database
-// methods.
-type MockWireDB struct {
- MockDB
- MockGetAllOrdersByAccountID func(ctx context.Context, accountID string) ([]string, error)
- MockGetDpopToken func(ctx context.Context, orderID string) (map[string]interface{}, error)
- MockCreateDpopToken func(ctx context.Context, orderID string, dpop map[string]interface{}) error
- MockGetOidcToken func(ctx context.Context, orderID string) (map[string]interface{}, error)
- MockCreateOidcToken func(ctx context.Context, orderID string, idToken map[string]interface{}) error
-}
-
// CreateAccount mock.
func (m *MockDB) CreateAccount(ctx context.Context, acc *Account) error {
if m.MockCreateAccount != nil {
@@ -417,49 +391,3 @@ func (m *MockDB) GetOrdersByAccountID(ctx context.Context, accID string) ([]stri
}
return m.MockRet1.([]string), m.MockError
}
-
-// GetAllOrdersByAccountID returns a list of any order IDs owned by the account.
-func (m *MockWireDB) GetAllOrdersByAccountID(ctx context.Context, accountID string) ([]string, error) {
- if m.MockGetAllOrdersByAccountID != nil {
- return m.MockGetAllOrdersByAccountID(ctx, accountID)
- } else if m.MockError != nil {
- return nil, m.MockError
- }
- return m.MockRet1.([]string), m.MockError
-}
-
-// GetDpop retrieves a DPoP from the database.
-func (m *MockWireDB) GetDpopToken(ctx context.Context, orderID string) (map[string]any, error) {
- if m.MockGetDpopToken != nil {
- return m.MockGetDpopToken(ctx, orderID)
- } else if m.MockError != nil {
- return nil, m.MockError
- }
- return m.MockRet1.(map[string]any), m.MockError
-}
-
-// CreateDpop creates DPoP resources and saves them to the DB.
-func (m *MockWireDB) CreateDpopToken(ctx context.Context, orderID string, dpop map[string]any) error {
- if m.MockCreateDpopToken != nil {
- return m.MockCreateDpopToken(ctx, orderID, dpop)
- }
- return m.MockError
-}
-
-// GetOidcToken retrieves an oidc token from the database.
-func (m *MockWireDB) GetOidcToken(ctx context.Context, orderID string) (map[string]any, error) {
- if m.MockGetOidcToken != nil {
- return m.MockGetOidcToken(ctx, orderID)
- } else if m.MockError != nil {
- return nil, m.MockError
- }
- return m.MockRet1.(map[string]any), m.MockError
-}
-
-// CreateOidcToken creates oidc token resources and saves them to the DB.
-func (m *MockWireDB) CreateOidcToken(ctx context.Context, orderID string, idToken map[string]any) error {
- if m.MockCreateOidcToken != nil {
- return m.MockCreateOidcToken(ctx, orderID, idToken)
- }
- return m.MockError
-}
diff --git a/vendor/github.com/smallstep/certificates/acme/db/nosql/account.go b/vendor/github.com/smallstep/certificates/acme/db/nosql/account.go
index 9b03db8..d590ccb 100644
--- a/vendor/github.com/smallstep/certificates/acme/db/nosql/account.go
+++ b/vendor/github.com/smallstep/certificates/acme/db/nosql/account.go
@@ -18,7 +18,6 @@ type dbAccount struct {
Contact []string `json:"contact,omitempty"`
Status acme.Status `json:"status"`
LocationPrefix string `json:"locationPrefix"`
- ProvisionerID string `json:"provisionerID,omitempty"`
ProvisionerName string `json:"provisionerName"`
CreatedAt time.Time `json:"createdAt"`
DeactivatedAt time.Time `json:"deactivatedAt"`
@@ -70,7 +69,6 @@ func (db *DB) GetAccount(ctx context.Context, id string) (*acme.Account, error)
Key: dbacc.Key,
ID: dbacc.ID,
LocationPrefix: dbacc.LocationPrefix,
- ProvisionerID: dbacc.ProvisionerID,
ProvisionerName: dbacc.ProvisionerName,
}, nil
}
@@ -99,7 +97,6 @@ func (db *DB) CreateAccount(ctx context.Context, acc *acme.Account) error {
Status: acc.Status,
CreatedAt: clock.Now(),
LocationPrefix: acc.LocationPrefix,
- ProvisionerID: acc.ProvisionerID,
ProvisionerName: acc.ProvisionerName,
}
diff --git a/vendor/github.com/smallstep/certificates/acme/db/nosql/challenge.go b/vendor/github.com/smallstep/certificates/acme/db/nosql/challenge.go
index e7c9aa2..9af1ae0 100644
--- a/vendor/github.com/smallstep/certificates/acme/db/nosql/challenge.go
+++ b/vendor/github.com/smallstep/certificates/acme/db/nosql/challenge.go
@@ -19,7 +19,6 @@ type dbChallenge struct {
Status acme.Status `json:"status"`
Token string `json:"token"`
Value string `json:"value"`
- Target string `json:"target,omitempty"`
ValidatedAt string `json:"validatedAt"`
CreatedAt time.Time `json:"createdAt"`
Error *acme.Error `json:"error"` // TODO(hs): a bit dangerous; should become db-specific type
@@ -62,7 +61,6 @@ func (db *DB) CreateChallenge(ctx context.Context, ch *acme.Challenge) error {
Token: ch.Token,
CreatedAt: clock.Now(),
Type: ch.Type,
- Target: ch.Target,
}
return db.save(ctx, ch.ID, dbch, nil, "challenge", challengeTable)
@@ -86,7 +84,6 @@ func (db *DB) GetChallenge(ctx context.Context, id, authzID string) (*acme.Chall
Token: dbch.Token,
Error: dbch.Error,
ValidatedAt: dbch.ValidatedAt,
- Target: dbch.Target,
}
return ch, nil
}
diff --git a/vendor/github.com/smallstep/certificates/acme/db/nosql/nosql.go b/vendor/github.com/smallstep/certificates/acme/db/nosql/nosql.go
index b2921f5..d19e298 100644
--- a/vendor/github.com/smallstep/certificates/acme/db/nosql/nosql.go
+++ b/vendor/github.com/smallstep/certificates/acme/db/nosql/nosql.go
@@ -23,8 +23,6 @@ var (
externalAccountKeyTable = []byte("acme_external_account_keys")
externalAccountKeyIDsByReferenceTable = []byte("acme_external_account_keyID_reference_index")
externalAccountKeyIDsByProvisionerIDTable = []byte("acme_external_account_keyID_provisionerID_index")
- wireDpopTokenTable = []byte("wire_acme_dpop_token")
- wireOidcTokenTable = []byte("wire_acme_oidc_token")
)
// DB is a struct that implements the AcmeDB interface.
@@ -38,11 +36,11 @@ func New(db nosqlDB.DB) (*DB, error) {
challengeTable, nonceTable, orderTable, ordersByAccountIDTable,
certTable, certBySerialTable, externalAccountKeyTable,
externalAccountKeyIDsByReferenceTable, externalAccountKeyIDsByProvisionerIDTable,
- wireDpopTokenTable, wireOidcTokenTable,
}
for _, b := range tables {
if err := db.CreateTable(b); err != nil {
- return nil, errors.Wrapf(err, "error creating table %s", string(b))
+ return nil, errors.Wrapf(err, "error creating table %s",
+ string(b))
}
}
return &DB{db}, nil
diff --git a/vendor/github.com/smallstep/certificates/acme/db/nosql/order.go b/vendor/github.com/smallstep/certificates/acme/db/nosql/order.go
index 983fbe8..fc8f211 100644
--- a/vendor/github.com/smallstep/certificates/acme/db/nosql/order.go
+++ b/vendor/github.com/smallstep/certificates/acme/db/nosql/order.go
@@ -98,7 +98,7 @@ func (db *DB) CreateOrder(ctx context.Context, o *acme.Order) error {
return err
}
- _, err = db.updateAddOrderIDs(ctx, o.AccountID, false, o.ID)
+ _, err = db.updateAddOrderIDs(ctx, o.AccountID, o.ID)
if err != nil {
return err
}
@@ -117,11 +117,10 @@ func (db *DB) UpdateOrder(ctx context.Context, o *acme.Order) error {
nu.Status = o.Status
nu.Error = o.Error
nu.CertificateID = o.CertificateID
-
return db.save(ctx, old.ID, nu, old, "order", orderTable)
}
-func (db *DB) updateAddOrderIDs(ctx context.Context, accID string, includeReadyOrders bool, addOids ...string) ([]string, error) {
+func (db *DB) updateAddOrderIDs(ctx context.Context, accID string, addOids ...string) ([]string, error) {
ordersByAccountMux.Lock()
defer ordersByAccountMux.Unlock()
@@ -152,8 +151,7 @@ func (db *DB) updateAddOrderIDs(ctx context.Context, accID string, includeReadyO
if err = o.UpdateStatus(ctx, db); err != nil {
return nil, acme.WrapErrorISE(err, "error updating order %s for account %s", oid, accID)
}
-
- if o.Status == acme.StatusPending || (o.Status == acme.StatusReady && includeReadyOrders) {
+ if o.Status == acme.StatusPending {
pendOids = append(pendOids, oid)
}
}
@@ -185,10 +183,5 @@ func (db *DB) updateAddOrderIDs(ctx context.Context, accID string, includeReadyO
// GetOrdersByAccountID returns a list of order IDs owned by the account.
func (db *DB) GetOrdersByAccountID(ctx context.Context, accID string) ([]string, error) {
- return db.updateAddOrderIDs(ctx, accID, false)
-}
-
-// GetAllOrdersByAccountID returns a list of any order IDs owned by the account.
-func (db *DB) GetAllOrdersByAccountID(ctx context.Context, accID string) ([]string, error) {
- return db.updateAddOrderIDs(ctx, accID, true)
+ return db.updateAddOrderIDs(ctx, accID)
}
diff --git a/vendor/github.com/smallstep/certificates/acme/db/nosql/wire.go b/vendor/github.com/smallstep/certificates/acme/db/nosql/wire.go
deleted file mode 100644
index 03b9350..0000000
--- a/vendor/github.com/smallstep/certificates/acme/db/nosql/wire.go
+++ /dev/null
@@ -1,121 +0,0 @@
-package nosql
-
-import (
- "context"
- "encoding/json"
- "fmt"
- "time"
-
- "github.com/smallstep/certificates/acme"
- "github.com/smallstep/nosql"
-)
-
-type dbDpopToken struct {
- ID string `json:"id"`
- Content []byte `json:"content"`
- CreatedAt time.Time `json:"createdAt"`
-}
-
-// getDBDpopToken retrieves and unmarshals an DPoP type from the database.
-func (db *DB) getDBDpopToken(_ context.Context, orderID string) (*dbDpopToken, error) {
- b, err := db.db.Get(wireDpopTokenTable, []byte(orderID))
- if err != nil {
- if nosql.IsErrNotFound(err) {
- return nil, acme.NewError(acme.ErrorMalformedType, "dpop token %q not found", orderID)
- }
- return nil, fmt.Errorf("failed loading dpop token %q: %w", orderID, err)
- }
-
- d := new(dbDpopToken)
- if err := json.Unmarshal(b, d); err != nil {
- return nil, fmt.Errorf("failed unmarshaling dpop token %q into dbDpopToken: %w", orderID, err)
- }
- return d, nil
-}
-
-// GetDpopToken retrieves an DPoP from the database.
-func (db *DB) GetDpopToken(ctx context.Context, orderID string) (map[string]any, error) {
- dbDpop, err := db.getDBDpopToken(ctx, orderID)
- if err != nil {
- return nil, err
- }
-
- dpop := make(map[string]any)
- err = json.Unmarshal(dbDpop.Content, &dpop)
-
- return dpop, err
-}
-
-// CreateDpopToken creates DPoP resources and saves them to the DB.
-func (db *DB) CreateDpopToken(ctx context.Context, orderID string, dpop map[string]any) error {
- content, err := json.Marshal(dpop)
- if err != nil {
- return fmt.Errorf("failed marshaling dpop token: %w", err)
- }
-
- now := clock.Now()
- dbDpop := &dbDpopToken{
- ID: orderID,
- Content: content,
- CreatedAt: now,
- }
- if err := db.save(ctx, orderID, dbDpop, nil, "dpop", wireDpopTokenTable); err != nil {
- return fmt.Errorf("failed saving dpop token: %w", err)
- }
- return nil
-}
-
-type dbOidcToken struct {
- ID string `json:"id"`
- Content []byte `json:"content"`
- CreatedAt time.Time `json:"createdAt"`
-}
-
-// getDBOidcToken retrieves and unmarshals an OIDC id token type from the database.
-func (db *DB) getDBOidcToken(_ context.Context, orderID string) (*dbOidcToken, error) {
- b, err := db.db.Get(wireOidcTokenTable, []byte(orderID))
- if err != nil {
- if nosql.IsErrNotFound(err) {
- return nil, acme.NewError(acme.ErrorMalformedType, "oidc token %q not found", orderID)
- }
- return nil, fmt.Errorf("failed loading oidc token %q: %w", orderID, err)
- }
-
- o := new(dbOidcToken)
- if err := json.Unmarshal(b, o); err != nil {
- return nil, fmt.Errorf("failed unmarshaling oidc token %q into dbOidcToken: %w", orderID, err)
- }
- return o, nil
-}
-
-// GetOidcToken retrieves an oidc token from the database.
-func (db *DB) GetOidcToken(ctx context.Context, orderID string) (map[string]any, error) {
- dbOidc, err := db.getDBOidcToken(ctx, orderID)
- if err != nil {
- return nil, err
- }
-
- idToken := make(map[string]any)
- err = json.Unmarshal(dbOidc.Content, &idToken)
-
- return idToken, err
-}
-
-// CreateOidcToken creates oidc token resources and saves them to the DB.
-func (db *DB) CreateOidcToken(ctx context.Context, orderID string, idToken map[string]any) error {
- content, err := json.Marshal(idToken)
- if err != nil {
- return fmt.Errorf("failed marshaling oidc token: %w", err)
- }
-
- now := clock.Now()
- dbOidc := &dbOidcToken{
- ID: orderID,
- Content: content,
- CreatedAt: now,
- }
- if err := db.save(ctx, orderID, dbOidc, nil, "oidc", wireOidcTokenTable); err != nil {
- return fmt.Errorf("failed saving oidc token: %w", err)
- }
- return nil
-}
diff --git a/vendor/github.com/smallstep/certificates/acme/errors.go b/vendor/github.com/smallstep/certificates/acme/errors.go
index 3c5fdb8..658ec6e 100644
--- a/vendor/github.com/smallstep/certificates/acme/errors.go
+++ b/vendor/github.com/smallstep/certificates/acme/errors.go
@@ -294,14 +294,14 @@ type Subproblem struct {
}
// NewError creates a new Error.
-func NewError(pt ProblemType, msg string, args ...any) *Error {
+func NewError(pt ProblemType, msg string, args ...interface{}) *Error {
return newError(pt, errors.Errorf(msg, args...))
}
// NewDetailedError creates a new Error that includes the error
// message in the details, providing more information to the
// ACME client.
-func NewDetailedError(pt ProblemType, msg string, args ...any) *Error {
+func NewDetailedError(pt ProblemType, msg string, args ...interface{}) *Error {
return NewError(pt, msg, args...).withDetail()
}
@@ -324,7 +324,7 @@ func (e *Error) AddSubproblems(subproblems ...Subproblem) *Error {
// NewSubproblem creates a new Subproblem. The msg and args
// are used to create a new error, which is set as the Detail, allowing
// for more detailed error messages to be returned to the ACME client.
-func NewSubproblem(pt ProblemType, msg string, args ...any) Subproblem {
+func NewSubproblem(pt ProblemType, msg string, args ...interface{}) Subproblem {
e := newError(pt, fmt.Errorf(msg, args...))
s := Subproblem{
Type: e.Type,
@@ -335,7 +335,7 @@ func NewSubproblem(pt ProblemType, msg string, args ...any) Subproblem {
// NewSubproblemWithIdentifier creates a new Subproblem with a specific ACME
// Identifier. It calls NewSubproblem and sets the Identifier.
-func NewSubproblemWithIdentifier(pt ProblemType, identifier Identifier, msg string, args ...any) Subproblem {
+func NewSubproblemWithIdentifier(pt ProblemType, identifier Identifier, msg string, args ...interface{}) Subproblem {
s := NewSubproblem(pt, msg, args...)
s.Identifier = &identifier
return s
@@ -362,12 +362,12 @@ func newError(pt ProblemType, err error) *Error {
}
// NewErrorISE creates a new ErrorServerInternalType Error.
-func NewErrorISE(msg string, args ...any) *Error {
+func NewErrorISE(msg string, args ...interface{}) *Error {
return NewError(ErrorServerInternalType, msg, args...)
}
// WrapError attempts to wrap the internal error.
-func WrapError(typ ProblemType, err error, msg string, args ...any) *Error {
+func WrapError(typ ProblemType, err error, msg string, args ...interface{}) *Error {
var e *Error
switch {
case err == nil:
@@ -384,12 +384,12 @@ func WrapError(typ ProblemType, err error, msg string, args ...any) *Error {
}
}
-func WrapDetailedError(typ ProblemType, err error, msg string, args ...any) *Error {
+func WrapDetailedError(typ ProblemType, err error, msg string, args ...interface{}) *Error {
return WrapError(typ, err, msg, args...).withDetail()
}
// WrapErrorISE shortcut to wrap an internal server error type.
-func WrapErrorISE(err error, msg string, args ...any) *Error {
+func WrapErrorISE(err error, msg string, args ...interface{}) *Error {
return WrapError(ErrorServerInternalType, err, msg, args...)
}
@@ -415,7 +415,7 @@ func (e *Error) Cause() error {
}
// ToLog implements the EnableLogger interface.
-func (e *Error) ToLog() (any, error) {
+func (e *Error) ToLog() (interface{}, error) {
b, err := json.Marshal(e)
if err != nil {
return nil, WrapErrorISE(err, "error marshaling acme.Error for logging")
@@ -424,7 +424,7 @@ func (e *Error) ToLog() (any, error) {
}
// Render implements render.RenderableError for Error.
-func (e *Error) Render(w http.ResponseWriter, r *http.Request) {
+func (e *Error) Render(w http.ResponseWriter) {
w.Header().Set("Content-Type", "application/problem+json")
- render.JSONStatus(w, r, e, e.StatusCode())
+ render.JSONStatus(w, e, e.StatusCode())
}
diff --git a/vendor/github.com/smallstep/certificates/acme/linker.go b/vendor/github.com/smallstep/certificates/acme/linker.go
index 18997c5..d142bf1 100644
--- a/vendor/github.com/smallstep/certificates/acme/linker.go
+++ b/vendor/github.com/smallstep/certificates/acme/linker.go
@@ -186,19 +186,19 @@ func (l *linker) Middleware(next http.Handler) http.Handler {
nameEscaped := chi.URLParam(r, "provisionerID")
name, err := url.PathUnescape(nameEscaped)
if err != nil {
- render.Error(w, r, WrapErrorISE(err, "error url unescaping provisioner name '%s'", nameEscaped))
+ render.Error(w, WrapErrorISE(err, "error url unescaping provisioner name '%s'", nameEscaped))
return
}
p, err := authority.MustFromContext(ctx).LoadProvisionerByName(name)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
acmeProv, ok := p.(*provisioner.ACME)
if !ok {
- render.Error(w, r, NewError(ErrorAccountDoesNotExistType, "provisioner must be of type ACME"))
+ render.Error(w, NewError(ErrorAccountDoesNotExistType, "provisioner must be of type ACME"))
return
}
diff --git a/vendor/github.com/smallstep/certificates/acme/order.go b/vendor/github.com/smallstep/certificates/acme/order.go
index c23befd..13c16b2 100644
--- a/vendor/github.com/smallstep/certificates/acme/order.go
+++ b/vendor/github.com/smallstep/certificates/acme/order.go
@@ -5,22 +5,15 @@ import (
"context"
"crypto/subtle"
"crypto/x509"
- "encoding/asn1"
"encoding/json"
- "errors"
- "fmt"
"net"
- "net/url"
"sort"
"strings"
"time"
+ "github.com/smallstep/certificates/authority/provisioner"
"go.step.sm/crypto/keyutil"
"go.step.sm/crypto/x509util"
-
- "github.com/smallstep/certificates/acme/wire"
- "github.com/smallstep/certificates/authority/provisioner"
- "github.com/smallstep/certificates/webhook"
)
type IdentifierType string
@@ -33,10 +26,6 @@ const (
// PermanentIdentifier is the ACME permanent-identifier identifier type
// defined in https://datatracker.ietf.org/doc/html/draft-bweeks-acme-device-attest-00
PermanentIdentifier IdentifierType = "permanent-identifier"
- // WireUser is the Wire user identifier type
- WireUser IdentifierType = "wireapp-user"
- // WireDevice is the Wire device identifier type
- WireDevice IdentifierType = "wireapp-device"
)
// Identifier encodes the type that an order pertains to.
@@ -132,11 +121,9 @@ func (o *Order) UpdateStatus(ctx context.Context, db DB) error {
default:
return NewErrorISE("unrecognized order status: %s", o.Status)
}
-
if err := db.UpdateOrder(ctx, o); err != nil {
return WrapErrorISE(err, "error updating order")
}
-
return nil
}
@@ -209,32 +196,7 @@ func (o *Order) Finalize(ctx context.Context, db DB, csr *x509.CertificateReques
// Template data
data := x509util.NewTemplateData()
- if o.containsWireIdentifiers() {
- wireDB, ok := db.(WireDB)
- if !ok {
- return fmt.Errorf("db %T is not a WireDB", db)
- }
- subject, err := createWireSubject(o, csr)
- if err != nil {
- return fmt.Errorf("failed creating Wire subject: %w", err)
- }
- data.SetSubject(subject)
-
- // Inject Wire's custom challenges into the template once they have been validated
- dpop, err := wireDB.GetDpopToken(ctx, o.ID)
- if err != nil {
- return fmt.Errorf("failed getting Wire DPoP token: %w", err)
- }
- data.Set("Dpop", dpop)
-
- oidc, err := wireDB.GetOidcToken(ctx, o.ID)
- if err != nil {
- return fmt.Errorf("failed getting Wire OIDC token: %w", err)
- }
- data.Set("Oidc", oidc)
- } else {
- data.SetCommonName(csr.Subject.CommonName)
- }
+ data.SetCommonName(csr.Subject.CommonName)
// Custom sign options passed to authority.Sign
var extraOptions []provisioner.SignOption
@@ -306,18 +268,6 @@ func (o *Order) Finalize(ctx context.Context, db DB, csr *x509.CertificateReques
NotAfter: provisioner.NewTimeDuration(o.NotAfter),
}, signOps...)
if err != nil {
- // Add subproblem for webhook errors, others can be added later.
- var webhookErr *webhook.Error
- if errors.As(err, &webhookErr) {
- //nolint:govet // ignore non-constant format string
- acmeError := NewDetailedError(ErrorUnauthorizedType, webhookErr.Error())
- acmeError.AddSubproblems(Subproblem{
- Type: fmt.Sprintf("urn:smallstep:acme:error:%s", webhookErr.Code),
- Detail: webhookErr.Message,
- })
- return acmeError
- }
-
return WrapErrorISE(err, "error signing certificate for order %s", o.ID)
}
@@ -333,76 +283,15 @@ func (o *Order) Finalize(ctx context.Context, db DB, csr *x509.CertificateReques
o.CertificateID = cert.ID
o.Status = StatusValid
-
if err = db.UpdateOrder(ctx, o); err != nil {
return WrapErrorISE(err, "error updating order %s", o.ID)
}
-
return nil
}
-// containsWireIdentifiers checks if [Order] contains ACME
-// identifiers for the WireUser or WireDevice types.
-func (o *Order) containsWireIdentifiers() bool {
- for _, i := range o.Identifiers {
- if i.Type == WireUser || i.Type == WireDevice {
- return true
- }
- }
- return false
-}
-
-// createWireSubject creates the subject for an [Order] with WireUser identifiers.
-func createWireSubject(o *Order, csr *x509.CertificateRequest) (subject x509util.Subject, err error) {
- wireUserIDs, wireDeviceIDs, otherIDs := 0, 0, 0
- for _, identifier := range o.Identifiers {
- switch identifier.Type {
- case WireUser:
- wireID, err := wire.ParseUserID(identifier.Value)
- if err != nil {
- return subject, NewErrorISE("unmarshal wireID: %s", err)
- }
-
- // TODO: temporarily using a custom OIDC for carrying the display name without having it listed as a DNS SAN.
- // reusing LDAP's OID for diplay name see http://oid-info.com/get/2.16.840.1.113730.3.1.241
- displayNameOid := asn1.ObjectIdentifier{2, 16, 840, 1, 113730, 3, 1, 241}
- var foundDisplayName = false
- for _, entry := range csr.Subject.Names {
- if entry.Type.Equal(displayNameOid) {
- foundDisplayName = true
- displayName := entry.Value.(string)
- if displayName != wireID.Name {
- return subject, NewErrorISE("expected displayName %v, found %v", wireID.Name, displayName)
- }
- }
- }
- if !foundDisplayName {
- return subject, NewErrorISE("CSR must contain the display name in '2.16.840.1.113730.3.1.241' OID")
- }
-
- if len(csr.Subject.Organization) == 0 || !strings.EqualFold(csr.Subject.Organization[0], wireID.Domain) {
- return subject, NewErrorISE("expected Organization [%s], found %v", wireID.Domain, csr.Subject.Organization)
- }
- subject.CommonName = wireID.Name
- subject.Organization = []string{wireID.Domain}
- wireUserIDs++
- case WireDevice:
- wireDeviceIDs++
- default:
- otherIDs++
- }
- }
-
- if otherIDs > 0 || wireUserIDs != 1 && wireDeviceIDs != 1 {
- return subject, NewErrorISE("order must have exactly one WireUser and WireDevice identifier")
- }
-
- return
-}
-
func (o *Order) sans(csr *x509.CertificateRequest) ([]x509util.SubjectAlternativeName, error) {
var sans []x509util.SubjectAlternativeName
- if len(csr.EmailAddresses) > 0 {
+ if len(csr.EmailAddresses) > 0 || len(csr.URIs) > 0 {
return sans, NewError(ErrorBadCSRType, "Only DNS names and IP addresses are allowed")
}
@@ -410,8 +299,7 @@ func (o *Order) sans(csr *x509.CertificateRequest) ([]x509util.SubjectAlternativ
orderNames := make([]string, numberOfIdentifierType(DNS, o.Identifiers))
orderIPs := make([]net.IP, numberOfIdentifierType(IP, o.Identifiers))
orderPIDs := make([]string, numberOfIdentifierType(PermanentIdentifier, o.Identifiers))
- tmpOrderURIs := make([]*url.URL, numberOfIdentifierType(WireUser, o.Identifiers)+numberOfIdentifierType(WireDevice, o.Identifiers))
- indexDNS, indexIP, indexPID, indexURI := 0, 0, 0, 0
+ indexDNS, indexIP, indexPID := 0, 0, 0
for _, n := range o.Identifiers {
switch n.Type {
case DNS:
@@ -423,37 +311,14 @@ func (o *Order) sans(csr *x509.CertificateRequest) ([]x509util.SubjectAlternativ
case PermanentIdentifier:
orderPIDs[indexPID] = n.Value
indexPID++
- case WireUser:
- wireID, err := wire.ParseUserID(n.Value)
- if err != nil {
- return sans, NewErrorISE("unsupported identifier value in order: %s", n.Value)
- }
- handle, err := url.Parse(wireID.Handle)
- if err != nil {
- return sans, NewErrorISE("handle must be a URI: %s", wireID.Handle)
- }
- tmpOrderURIs[indexURI] = handle
- indexURI++
- case WireDevice:
- wireID, err := wire.ParseDeviceID(n.Value)
- if err != nil {
- return sans, NewErrorISE("unsupported identifier value in order: %s", n.Value)
- }
- clientID, err := url.Parse(wireID.ClientID)
- if err != nil {
- return sans, NewErrorISE("clientId must be a URI: %s", wireID.ClientID)
- }
- tmpOrderURIs[indexURI] = clientID
- indexURI++
default:
return sans, NewErrorISE("unsupported identifier type in order: %s", n.Type)
}
}
orderNames = uniqueSortedLowerNames(orderNames)
orderIPs = uniqueSortedIPs(orderIPs)
- orderURIs := uniqueSortedURIStrings(tmpOrderURIs)
- totalNumberOfSANs := len(csr.DNSNames) + len(csr.IPAddresses) + len(csr.URIs)
+ totalNumberOfSANs := len(csr.DNSNames) + len(csr.IPAddresses)
sans = make([]x509util.SubjectAlternativeName, totalNumberOfSANs)
index := 0
@@ -496,26 +361,6 @@ func (o *Order) sans(csr *x509.CertificateRequest) ([]x509util.SubjectAlternativ
index++
}
- if len(csr.URIs) != len(tmpOrderURIs) {
- return sans, NewError(ErrorBadCSRType, "CSR URIs do not match identifiers exactly: "+
- "CSR URIs = %v, Order URIs = %v", csr.URIs, tmpOrderURIs)
- }
-
- // sort URI list
- csrURIs := uniqueSortedURIStrings(csr.URIs)
-
- for i := range csrURIs {
- if csrURIs[i] != orderURIs[i] {
- return sans, NewError(ErrorBadCSRType, "CSR URIs do not match identifiers exactly: "+
- "CSR URIs = %v, Order URIs = %v", csr.URIs, tmpOrderURIs)
- }
- sans[index] = x509util.SubjectAlternativeName{
- Type: x509util.URIType,
- Value: orderURIs[i],
- }
- index++
- }
-
return sans, nil
}
@@ -585,21 +430,6 @@ func uniqueSortedLowerNames(names []string) (unique []string) {
}
unique = make([]string, 0, len(nameMap))
for name := range nameMap {
- if name != "" {
- unique = append(unique, name)
- }
- }
- sort.Strings(unique)
- return
-}
-
-func uniqueSortedURIStrings(uris []*url.URL) (unique []string) {
- uriMap := make(map[string]struct{}, len(uris))
- for _, name := range uris {
- uriMap[name.String()] = struct{}{}
- }
- unique = make([]string, 0, len(uriMap))
- for name := range uriMap {
unique = append(unique, name)
}
sort.Strings(unique)
diff --git a/vendor/github.com/smallstep/certificates/acme/wire/id.go b/vendor/github.com/smallstep/certificates/acme/wire/id.go
deleted file mode 100644
index 5b77f08..0000000
--- a/vendor/github.com/smallstep/certificates/acme/wire/id.go
+++ /dev/null
@@ -1,91 +0,0 @@
-package wire
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "net/url"
- "strings"
-)
-
-type UserID struct {
- Name string `json:"name,omitempty"`
- Domain string `json:"domain,omitempty"`
- Handle string `json:"handle,omitempty"`
-}
-
-type DeviceID struct {
- Name string `json:"name,omitempty"`
- Domain string `json:"domain,omitempty"`
- ClientID string `json:"client-id,omitempty"`
- Handle string `json:"handle,omitempty"`
-}
-
-func ParseUserID(value string) (id UserID, err error) {
- if err = json.Unmarshal([]byte(value), &id); err != nil {
- return
- }
-
- switch {
- case id.Handle == "":
- err = errors.New("handle must not be empty")
- case id.Name == "":
- err = errors.New("name must not be empty")
- case id.Domain == "":
- err = errors.New("domain must not be empty")
- }
-
- return
-}
-
-func ParseDeviceID(value string) (id DeviceID, err error) {
- if err = json.Unmarshal([]byte(value), &id); err != nil {
- return
- }
-
- switch {
- case id.Handle == "":
- err = errors.New("handle must not be empty")
- case id.Name == "":
- err = errors.New("name must not be empty")
- case id.Domain == "":
- err = errors.New("domain must not be empty")
- case id.ClientID == "":
- err = errors.New("client-id must not be empty")
- }
-
- return
-}
-
-type ClientID struct {
- Scheme string
- Username string
- DeviceID string
- Domain string
-}
-
-// ParseClientID parses a Wire clientID. The ClientID format is as follows:
-//
-// "wireapp://CzbfFjDOQrenCbDxVmgnFw!594930e9d50bb175@wire.com",
-//
-// where '!' is used as a separator between the user id & device id.
-func ParseClientID(clientID string) (ClientID, error) {
- clientIDURI, err := url.Parse(clientID)
- if err != nil {
- return ClientID{}, fmt.Errorf("invalid Wire client ID URI %q: %w", clientID, err)
- }
- if clientIDURI.Scheme != "wireapp" {
- return ClientID{}, fmt.Errorf("invalid Wire client ID scheme %q; expected \"wireapp\"", clientIDURI.Scheme)
- }
- fullUsername := clientIDURI.User.Username()
- parts := strings.SplitN(fullUsername, "!", 2)
- if len(parts) != 2 {
- return ClientID{}, fmt.Errorf("invalid Wire client ID username %q", fullUsername)
- }
- return ClientID{
- Scheme: clientIDURI.Scheme,
- Username: parts[0],
- DeviceID: parts[1],
- Domain: clientIDURI.Host,
- }, nil
-}
diff --git a/vendor/github.com/smallstep/certificates/api/api.go b/vendor/github.com/smallstep/certificates/api/api.go
index fa55449..6916983 100644
--- a/vendor/github.com/smallstep/certificates/api/api.go
+++ b/vendor/github.com/smallstep/certificates/api/api.go
@@ -4,7 +4,7 @@ import (
"bytes"
"context"
"crypto"
- "crypto/dsa" // support legacy algorithms
+ "crypto/dsa" //nolint:staticcheck // support legacy algorithms
"crypto/ecdsa"
"crypto/ed25519"
"crypto/rsa"
@@ -52,7 +52,6 @@ type Authority interface {
Revoke(context.Context, *authority.RevokeOptions) error
GetEncryptedKey(kid string) (string, error)
GetRoots() ([]*x509.Certificate, error)
- GetIntermediateCertificates() []*x509.Certificate
GetFederation() ([]*x509.Certificate, error)
Version() authority.Version
GetCertificateRevocationList() (*authority.CertificateRevocationListInfo, error)
@@ -296,11 +295,6 @@ type RootsResponse struct {
Certificates []Certificate `json:"crts"`
}
-// IntermediatesResponse is the response object of the intermediates request.
-type IntermediatesResponse struct {
- Certificates []Certificate `json:"crts"`
-}
-
// FederationResponse is the response object of the federation request.
type FederationResponse struct {
Certificates []Certificate `json:"crts"`
@@ -336,10 +330,7 @@ func Route(r Router) {
r.MethodFunc("GET", "/provisioners/{kid}/encrypted-key", ProvisionerKey)
r.MethodFunc("GET", "/roots", Roots)
r.MethodFunc("GET", "/roots.pem", RootsPEM)
- r.MethodFunc("GET", "/intermediates", Intermediates)
- r.MethodFunc("GET", "/intermediates.pem", IntermediatesPEM)
r.MethodFunc("GET", "/federation", Federation)
-
// SSH CA
r.MethodFunc("POST", "/ssh/sign", SSHSign)
r.MethodFunc("POST", "/ssh/renew", SSHRenew)
@@ -362,15 +353,15 @@ func Route(r Router) {
// Version is an HTTP handler that returns the version of the server.
func Version(w http.ResponseWriter, r *http.Request) {
v := mustAuthority(r.Context()).Version()
- render.JSON(w, r, VersionResponse{
+ render.JSON(w, VersionResponse{
Version: v.Version,
RequireClientAuthentication: v.RequireClientAuthentication,
})
}
// Health is an HTTP handler that returns the status of the server.
-func Health(w http.ResponseWriter, r *http.Request) {
- render.JSON(w, r, HealthResponse{Status: "ok"})
+func Health(w http.ResponseWriter, _ *http.Request) {
+ render.JSON(w, HealthResponse{Status: "ok"})
}
// Root is an HTTP handler that using the SHA256 from the URL, returns the root
@@ -381,11 +372,11 @@ func Root(w http.ResponseWriter, r *http.Request) {
// Load root certificate with the
cert, err := mustAuthority(r.Context()).Root(sum)
if err != nil {
- render.Error(w, r, errs.Wrapf(http.StatusNotFound, err, "%s was not found", r.RequestURI))
+ render.Error(w, errs.Wrapf(http.StatusNotFound, err, "%s was not found", r.RequestURI))
return
}
- render.JSON(w, r, &RootResponse{RootPEM: Certificate{cert}})
+ render.JSON(w, &RootResponse{RootPEM: Certificate{cert}})
}
func certChainToPEM(certChain []*x509.Certificate) []Certificate {
@@ -400,17 +391,17 @@ func certChainToPEM(certChain []*x509.Certificate) []Certificate {
func Provisioners(w http.ResponseWriter, r *http.Request) {
cursor, limit, err := ParseCursor(r)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
p, next, err := mustAuthority(r.Context()).GetProvisioners(cursor, limit)
if err != nil {
- render.Error(w, r, errs.InternalServerErr(err))
+ render.Error(w, errs.InternalServerErr(err))
return
}
- render.JSON(w, r, &ProvisionersResponse{
+ render.JSON(w, &ProvisionersResponse{
Provisioners: p,
NextCursor: next,
})
@@ -421,18 +412,18 @@ func ProvisionerKey(w http.ResponseWriter, r *http.Request) {
kid := chi.URLParam(r, "kid")
key, err := mustAuthority(r.Context()).GetEncryptedKey(kid)
if err != nil {
- render.Error(w, r, errs.NotFoundErr(err))
+ render.Error(w, errs.NotFoundErr(err))
return
}
- render.JSON(w, r, &ProvisionerKeyResponse{key})
+ render.JSON(w, &ProvisionerKeyResponse{key})
}
// Roots returns all the root certificates for the CA.
func Roots(w http.ResponseWriter, r *http.Request) {
roots, err := mustAuthority(r.Context()).GetRoots()
if err != nil {
- render.Error(w, r, errs.ForbiddenErr(err, "error getting roots"))
+ render.Error(w, errs.ForbiddenErr(err, "error getting roots"))
return
}
@@ -441,7 +432,7 @@ func Roots(w http.ResponseWriter, r *http.Request) {
certs[i] = Certificate{roots[i]}
}
- render.JSONStatus(w, r, &RootsResponse{
+ render.JSONStatus(w, &RootsResponse{
Certificates: certs,
}, http.StatusCreated)
}
@@ -450,7 +441,7 @@ func Roots(w http.ResponseWriter, r *http.Request) {
func RootsPEM(w http.ResponseWriter, r *http.Request) {
roots, err := mustAuthority(r.Context()).GetRoots()
if err != nil {
- render.Error(w, r, errs.InternalServerErr(err))
+ render.Error(w, errs.InternalServerErr(err))
return
}
@@ -463,48 +454,7 @@ func RootsPEM(w http.ResponseWriter, r *http.Request) {
})
if _, err := w.Write(block); err != nil {
- log.Error(w, r, err)
- return
- }
- }
-}
-
-// Intermediates returns all the intermediate certificates of the CA.
-func Intermediates(w http.ResponseWriter, r *http.Request) {
- intermediates := mustAuthority(r.Context()).GetIntermediateCertificates()
- if len(intermediates) == 0 {
- render.Error(w, r, errs.NotImplemented("error getting intermediates: method not implemented"))
- return
- }
-
- certs := make([]Certificate, len(intermediates))
- for i := range intermediates {
- certs[i] = Certificate{intermediates[i]}
- }
-
- render.JSONStatus(w, r, &IntermediatesResponse{
- Certificates: certs,
- }, http.StatusCreated)
-}
-
-// IntermediatesPEM returns all the intermediate certificates for the CA in PEM format.
-func IntermediatesPEM(w http.ResponseWriter, r *http.Request) {
- intermediates := mustAuthority(r.Context()).GetIntermediateCertificates()
- if len(intermediates) == 0 {
- render.Error(w, r, errs.NotImplemented("error getting intermediates: method not implemented"))
- return
- }
-
- w.Header().Set("Content-Type", "application/x-pem-file")
-
- for _, crt := range intermediates {
- block := pem.EncodeToMemory(&pem.Block{
- Type: "CERTIFICATE",
- Bytes: crt.Raw,
- })
-
- if _, err := w.Write(block); err != nil {
- log.Error(w, r, err)
+ log.Error(w, err)
return
}
}
@@ -514,7 +464,7 @@ func IntermediatesPEM(w http.ResponseWriter, r *http.Request) {
func Federation(w http.ResponseWriter, r *http.Request) {
federated, err := mustAuthority(r.Context()).GetFederation()
if err != nil {
- render.Error(w, r, errs.ForbiddenErr(err, "error getting federated roots"))
+ render.Error(w, errs.ForbiddenErr(err, "error getting federated roots"))
return
}
@@ -523,7 +473,7 @@ func Federation(w http.ResponseWriter, r *http.Request) {
certs[i] = Certificate{federated[i]}
}
- render.JSONStatus(w, r, &FederationResponse{
+ render.JSONStatus(w, &FederationResponse{
Certificates: certs,
}, http.StatusCreated)
}
diff --git a/vendor/github.com/smallstep/certificates/api/crl.go b/vendor/github.com/smallstep/certificates/api/crl.go
index 92e1481..c10d08c 100644
--- a/vendor/github.com/smallstep/certificates/api/crl.go
+++ b/vendor/github.com/smallstep/certificates/api/crl.go
@@ -13,12 +13,12 @@ import (
func CRL(w http.ResponseWriter, r *http.Request) {
crlInfo, err := mustAuthority(r.Context()).GetCertificateRevocationList()
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
if crlInfo == nil {
- render.Error(w, r, errs.New(http.StatusNotFound, "no CRL available"))
+ render.Error(w, errs.New(http.StatusNotFound, "no CRL available"))
return
}
diff --git a/vendor/github.com/smallstep/certificates/api/log/log.go b/vendor/github.com/smallstep/certificates/api/log/log.go
index 6cc61a7..687d61c 100644
--- a/vendor/github.com/smallstep/certificates/api/log/log.go
+++ b/vendor/github.com/smallstep/certificates/api/log/log.go
@@ -2,7 +2,6 @@
package log
import (
- "context"
"fmt"
"net/http"
"os"
@@ -10,29 +9,6 @@ import (
"github.com/pkg/errors"
)
-type errorLoggerKey struct{}
-
-// ErrorLogger is the function type used to log errors.
-type ErrorLogger func(http.ResponseWriter, *http.Request, error)
-
-func (fn ErrorLogger) call(w http.ResponseWriter, r *http.Request, err error) {
- if fn == nil {
- return
- }
- fn(w, r, err)
-}
-
-// WithErrorLogger returns a new context with the given error logger.
-func WithErrorLogger(ctx context.Context, fn ErrorLogger) context.Context {
- return context.WithValue(ctx, errorLoggerKey{}, fn)
-}
-
-// ErrorLoggerFromContext returns an error logger from the context.
-func ErrorLoggerFromContext(ctx context.Context) (fn ErrorLogger) {
- fn, _ = ctx.Value(errorLoggerKey{}).(ErrorLogger)
- return
-}
-
// StackTracedError is the set of errors implementing the StackTrace function.
//
// Errors implementing this interface have their stack traces logged when passed
@@ -51,10 +27,8 @@ type fieldCarrier interface {
// Error adds to the response writer the given error if it implements
// logging.ResponseLogger. If it does not implement it, then writes the error
// using the log package.
-func Error(w http.ResponseWriter, r *http.Request, err error) {
- ErrorLoggerFromContext(r.Context()).call(w, r, err)
-
- fc, ok := w.(fieldCarrier)
+func Error(rw http.ResponseWriter, err error) {
+ fc, ok := rw.(fieldCarrier)
if !ok {
return
}
@@ -77,7 +51,7 @@ func Error(w http.ResponseWriter, r *http.Request, err error) {
// EnabledResponse log the response object if it implements the EnableLogger
// interface.
-func EnabledResponse(rw http.ResponseWriter, r *http.Request, v any) {
+func EnabledResponse(rw http.ResponseWriter, v any) {
type enableLogger interface {
ToLog() (any, error)
}
@@ -85,7 +59,7 @@ func EnabledResponse(rw http.ResponseWriter, r *http.Request, v any) {
if el, ok := v.(enableLogger); ok {
out, err := el.ToLog()
if err != nil {
- Error(rw, r, err)
+ Error(rw, err)
return
}
diff --git a/vendor/github.com/smallstep/certificates/api/read/read.go b/vendor/github.com/smallstep/certificates/api/read/read.go
index 6f75c41..72530b8 100644
--- a/vendor/github.com/smallstep/certificates/api/read/read.go
+++ b/vendor/github.com/smallstep/certificates/api/read/read.go
@@ -51,7 +51,7 @@ func (e badProtoJSONError) Error() string {
}
// Render implements render.RenderableError for badProtoJSONError
-func (e badProtoJSONError) Render(w http.ResponseWriter, r *http.Request) {
+func (e badProtoJSONError) Render(w http.ResponseWriter) {
v := struct {
Type string `json:"type"`
Detail string `json:"detail"`
@@ -62,5 +62,5 @@ func (e badProtoJSONError) Render(w http.ResponseWriter, r *http.Request) {
// trim the proto prefix for the message
Message: strings.TrimSpace(strings.TrimPrefix(e.Error(), "proto:")),
}
- render.JSONStatus(w, r, v, http.StatusBadRequest)
+ render.JSONStatus(w, v, http.StatusBadRequest)
}
diff --git a/vendor/github.com/smallstep/certificates/api/rekey.go b/vendor/github.com/smallstep/certificates/api/rekey.go
index 772de21..cda843a 100644
--- a/vendor/github.com/smallstep/certificates/api/rekey.go
+++ b/vendor/github.com/smallstep/certificates/api/rekey.go
@@ -29,25 +29,25 @@ func (s *RekeyRequest) Validate() error {
// Rekey is similar to renew except that the certificate will be renewed with new key from csr.
func Rekey(w http.ResponseWriter, r *http.Request) {
if r.TLS == nil || len(r.TLS.PeerCertificates) == 0 {
- render.Error(w, r, errs.BadRequest("missing client certificate"))
+ render.Error(w, errs.BadRequest("missing client certificate"))
return
}
var body RekeyRequest
if err := read.JSON(r.Body, &body); err != nil {
- render.Error(w, r, errs.BadRequestErr(err, "error reading request body"))
+ render.Error(w, errs.BadRequestErr(err, "error reading request body"))
return
}
if err := body.Validate(); err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
a := mustAuthority(r.Context())
certChain, err := a.Rekey(r.TLS.PeerCertificates[0], body.CsrPEM.CertificateRequest.PublicKey)
if err != nil {
- render.Error(w, r, errs.Wrap(http.StatusInternalServerError, err, "cahandler.Rekey"))
+ render.Error(w, errs.Wrap(http.StatusInternalServerError, err, "cahandler.Rekey"))
return
}
certChainPEM := certChainToPEM(certChain)
@@ -57,7 +57,7 @@ func Rekey(w http.ResponseWriter, r *http.Request) {
}
LogCertificate(w, certChain[0])
- render.JSONStatus(w, r, &SignResponse{
+ render.JSONStatus(w, &SignResponse{
ServerPEM: certChainPEM[0],
CaPEM: caPEM,
CertChainPEM: certChainPEM,
diff --git a/vendor/github.com/smallstep/certificates/api/render/render.go b/vendor/github.com/smallstep/certificates/api/render/render.go
index 1c66280..7829ba2 100644
--- a/vendor/github.com/smallstep/certificates/api/render/render.go
+++ b/vendor/github.com/smallstep/certificates/api/render/render.go
@@ -13,8 +13,8 @@ import (
)
// JSON is shorthand for JSONStatus(w, v, http.StatusOK).
-func JSON(w http.ResponseWriter, r *http.Request, v interface{}) {
- JSONStatus(w, r, v, http.StatusOK)
+func JSON(w http.ResponseWriter, v interface{}) {
+ JSONStatus(w, v, http.StatusOK)
}
// JSONStatus marshals v into w. It additionally sets the status code of
@@ -22,7 +22,7 @@ func JSON(w http.ResponseWriter, r *http.Request, v interface{}) {
//
// JSONStatus sets the Content-Type of w to application/json unless one is
// specified.
-func JSONStatus(w http.ResponseWriter, r *http.Request, v interface{}, status int) {
+func JSONStatus(w http.ResponseWriter, v interface{}, status int) {
setContentTypeUnlessPresent(w, "application/json")
w.WriteHeader(status)
@@ -43,7 +43,7 @@ func JSONStatus(w http.ResponseWriter, r *http.Request, v interface{}, status in
}
}
- log.EnabledResponse(w, r, v)
+ log.EnabledResponse(w, v)
}
// ProtoJSON is shorthand for ProtoJSONStatus(w, m, http.StatusOK).
@@ -80,22 +80,22 @@ func setContentTypeUnlessPresent(w http.ResponseWriter, contentType string) {
type RenderableError interface {
error
- Render(http.ResponseWriter, *http.Request)
+ Render(http.ResponseWriter)
}
// Error marshals the JSON representation of err to w. In case err implements
// RenderableError its own Render method will be called instead.
-func Error(rw http.ResponseWriter, r *http.Request, err error) {
- log.Error(rw, r, err)
+func Error(w http.ResponseWriter, err error) {
+ log.Error(w, err)
- var re RenderableError
- if errors.As(err, &re) {
- re.Render(rw, r)
+ var r RenderableError
+ if errors.As(err, &r) {
+ r.Render(w)
return
}
- JSONStatus(rw, r, err, statusCodeFromError(err))
+ JSONStatus(w, err, statusCodeFromError(err))
}
// StatusCodedError is the set of errors that implement the basic StatusCode
diff --git a/vendor/github.com/smallstep/certificates/api/renew.go b/vendor/github.com/smallstep/certificates/api/renew.go
index 7cd3707..1b9ed95 100644
--- a/vendor/github.com/smallstep/certificates/api/renew.go
+++ b/vendor/github.com/smallstep/certificates/api/renew.go
@@ -23,20 +23,19 @@ func Renew(w http.ResponseWriter, r *http.Request) {
// Get the leaf certificate from the peer or the token.
cert, token, err := getPeerCertificate(r)
if err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
// The token can be used by RAs to renew a certificate.
if token != "" {
ctx = authority.NewTokenContext(ctx, token)
- logOtt(w, token)
}
a := mustAuthority(ctx)
certChain, err := a.RenewContext(ctx, cert, nil)
if err != nil {
- render.Error(w, r, errs.Wrap(http.StatusInternalServerError, err, "cahandler.Renew"))
+ render.Error(w, errs.Wrap(http.StatusInternalServerError, err, "cahandler.Renew"))
return
}
certChainPEM := certChainToPEM(certChain)
@@ -46,7 +45,7 @@ func Renew(w http.ResponseWriter, r *http.Request) {
}
LogCertificate(w, certChain[0])
- render.JSONStatus(w, r, &SignResponse{
+ render.JSONStatus(w, &SignResponse{
ServerPEM: certChainPEM[0],
CaPEM: caPEM,
CertChainPEM: certChainPEM,
diff --git a/vendor/github.com/smallstep/certificates/api/revoke.go b/vendor/github.com/smallstep/certificates/api/revoke.go
index 41969c0..dc639d5 100644
--- a/vendor/github.com/smallstep/certificates/api/revoke.go
+++ b/vendor/github.com/smallstep/certificates/api/revoke.go
@@ -57,12 +57,12 @@ func (r *RevokeRequest) Validate() (err error) {
func Revoke(w http.ResponseWriter, r *http.Request) {
var body RevokeRequest
if err := read.JSON(r.Body, &body); err != nil {
- render.Error(w, r, errs.BadRequestErr(err, "error reading request body"))
+ render.Error(w, errs.BadRequestErr(err, "error reading request body"))
return
}
if err := body.Validate(); err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
@@ -81,7 +81,7 @@ func Revoke(w http.ResponseWriter, r *http.Request) {
if body.OTT != "" {
logOtt(w, body.OTT)
if _, err := a.Authorize(ctx, body.OTT); err != nil {
- render.Error(w, r, errs.UnauthorizedErr(err))
+ render.Error(w, errs.UnauthorizedErr(err))
return
}
opts.OTT = body.OTT
@@ -90,12 +90,12 @@ func Revoke(w http.ResponseWriter, r *http.Request) {
// the client certificate Serial Number must match the serial number
// being revoked.
if r.TLS == nil || len(r.TLS.PeerCertificates) == 0 {
- render.Error(w, r, errs.BadRequest("missing ott or client certificate"))
+ render.Error(w, errs.BadRequest("missing ott or client certificate"))
return
}
opts.Crt = r.TLS.PeerCertificates[0]
if opts.Crt.SerialNumber.String() != opts.Serial {
- render.Error(w, r, errs.BadRequest("serial number in client certificate different than body"))
+ render.Error(w, errs.BadRequest("serial number in client certificate different than body"))
return
}
// TODO: should probably be checking if the certificate was revoked here.
@@ -106,12 +106,12 @@ func Revoke(w http.ResponseWriter, r *http.Request) {
}
if err := a.Revoke(ctx, opts); err != nil {
- render.Error(w, r, errs.ForbiddenErr(err, "error revoking certificate"))
+ render.Error(w, errs.ForbiddenErr(err, "error revoking certificate"))
return
}
logRevoke(w, opts)
- render.JSON(w, r, &RevokeResponse{Status: "ok"})
+ render.JSON(w, &RevokeResponse{Status: "ok"})
}
func logRevoke(w http.ResponseWriter, ri *authority.RevokeOptions) {
diff --git a/vendor/github.com/smallstep/certificates/api/sign.go b/vendor/github.com/smallstep/certificates/api/sign.go
index bff4176..26b3c39 100644
--- a/vendor/github.com/smallstep/certificates/api/sign.go
+++ b/vendor/github.com/smallstep/certificates/api/sign.go
@@ -52,13 +52,13 @@ type SignResponse struct {
func Sign(w http.ResponseWriter, r *http.Request) {
var body SignRequest
if err := read.JSON(r.Body, &body); err != nil {
- render.Error(w, r, errs.BadRequestErr(err, "error reading request body"))
+ render.Error(w, errs.BadRequestErr(err, "error reading request body"))
return
}
logOtt(w, body.OTT)
if err := body.Validate(); err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
@@ -74,13 +74,13 @@ func Sign(w http.ResponseWriter, r *http.Request) {
ctx = provisioner.NewContextWithMethod(ctx, provisioner.SignMethod)
signOpts, err := a.Authorize(ctx, body.OTT)
if err != nil {
- render.Error(w, r, errs.UnauthorizedErr(err))
+ render.Error(w, errs.UnauthorizedErr(err))
return
}
certChain, err := a.SignWithContext(ctx, body.CsrPEM.CertificateRequest, opts, signOpts...)
if err != nil {
- render.Error(w, r, errs.ForbiddenErr(err, "error signing certificate"))
+ render.Error(w, errs.ForbiddenErr(err, "error signing certificate"))
return
}
certChainPEM := certChainToPEM(certChain)
@@ -90,7 +90,7 @@ func Sign(w http.ResponseWriter, r *http.Request) {
}
LogCertificate(w, certChain[0])
- render.JSONStatus(w, r, &SignResponse{
+ render.JSONStatus(w, &SignResponse{
ServerPEM: certChainPEM[0],
CaPEM: caPEM,
CertChainPEM: certChainPEM,
diff --git a/vendor/github.com/smallstep/certificates/api/ssh.go b/vendor/github.com/smallstep/certificates/api/ssh.go
index e1024f3..08294c7 100644
--- a/vendor/github.com/smallstep/certificates/api/ssh.go
+++ b/vendor/github.com/smallstep/certificates/api/ssh.go
@@ -6,11 +6,8 @@ import (
"encoding/base64"
"encoding/json"
"net/http"
- "net/url"
- "strings"
"time"
- "github.com/google/uuid"
"github.com/pkg/errors"
"golang.org/x/crypto/ssh"
@@ -256,19 +253,19 @@ type SSHBastionResponse struct {
func SSHSign(w http.ResponseWriter, r *http.Request) {
var body SSHSignRequest
if err := read.JSON(r.Body, &body); err != nil {
- render.Error(w, r, errs.BadRequestErr(err, "error reading request body"))
+ render.Error(w, errs.BadRequestErr(err, "error reading request body"))
return
}
logOtt(w, body.OTT)
if err := body.Validate(); err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
publicKey, err := ssh.ParsePublicKey(body.PublicKey)
if err != nil {
- render.Error(w, r, errs.BadRequestErr(err, "error parsing publicKey"))
+ render.Error(w, errs.BadRequestErr(err, "error parsing publicKey"))
return
}
@@ -276,7 +273,7 @@ func SSHSign(w http.ResponseWriter, r *http.Request) {
if body.AddUserPublicKey != nil {
addUserPublicKey, err = ssh.ParsePublicKey(body.AddUserPublicKey)
if err != nil {
- render.Error(w, r, errs.BadRequestErr(err, "error parsing addUserPublicKey"))
+ render.Error(w, errs.BadRequestErr(err, "error parsing addUserPublicKey"))
return
}
}
@@ -292,18 +289,17 @@ func SSHSign(w http.ResponseWriter, r *http.Request) {
ctx := provisioner.NewContextWithMethod(r.Context(), provisioner.SSHSignMethod)
ctx = provisioner.NewContextWithToken(ctx, body.OTT)
- ctx = provisioner.NewContextWithCertType(ctx, opts.CertType)
a := mustAuthority(ctx)
signOpts, err := a.Authorize(ctx, body.OTT)
if err != nil {
- render.Error(w, r, errs.UnauthorizedErr(err))
+ render.Error(w, errs.UnauthorizedErr(err))
return
}
cert, err := a.SignSSH(ctx, publicKey, opts, signOpts...)
if err != nil {
- render.Error(w, r, errs.ForbiddenErr(err, "error signing ssh certificate"))
+ render.Error(w, errs.ForbiddenErr(err, "error signing ssh certificate"))
return
}
@@ -311,7 +307,7 @@ func SSHSign(w http.ResponseWriter, r *http.Request) {
if addUserPublicKey != nil && authority.IsValidForAddUser(cert) == nil {
addUserCert, err := a.SignSSHAddUser(ctx, addUserPublicKey, cert)
if err != nil {
- render.Error(w, r, errs.ForbiddenErr(err, "error signing ssh certificate"))
+ render.Error(w, errs.ForbiddenErr(err, "error signing ssh certificate"))
return
}
addUserCertificate = &SSHCertificate{addUserCert}
@@ -324,27 +320,26 @@ func SSHSign(w http.ResponseWriter, r *http.Request) {
ctx = provisioner.NewContextWithMethod(ctx, provisioner.SignIdentityMethod)
signOpts, err := a.Authorize(ctx, body.OTT)
if err != nil {
- render.Error(w, r, errs.UnauthorizedErr(err))
+ render.Error(w, errs.UnauthorizedErr(err))
return
}
// Enforce the same duration as ssh certificate.
signOpts = append(signOpts, &identityModifier{
- Identity: getIdentityURI(cr),
NotBefore: time.Unix(int64(cert.ValidAfter), 0),
NotAfter: time.Unix(int64(cert.ValidBefore), 0),
})
certChain, err := a.SignWithContext(ctx, cr, provisioner.SignOptions{}, signOpts...)
if err != nil {
- render.Error(w, r, errs.ForbiddenErr(err, "error signing identity certificate"))
+ render.Error(w, errs.ForbiddenErr(err, "error signing identity certificate"))
return
}
identityCertificate = certChainToPEM(certChain)
}
LogSSHCertificate(w, cert)
- render.JSONStatus(w, r, &SSHSignResponse{
+ render.JSONStatus(w, &SSHSignResponse{
Certificate: SSHCertificate{cert},
AddUserCertificate: addUserCertificate,
IdentityCertificate: identityCertificate,
@@ -357,12 +352,12 @@ func SSHRoots(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
keys, err := mustAuthority(ctx).GetSSHRoots(ctx)
if err != nil {
- render.Error(w, r, errs.InternalServerErr(err))
+ render.Error(w, errs.InternalServerErr(err))
return
}
if len(keys.HostKeys) == 0 && len(keys.UserKeys) == 0 {
- render.Error(w, r, errs.NotFound("no keys found"))
+ render.Error(w, errs.NotFound("no keys found"))
return
}
@@ -374,7 +369,7 @@ func SSHRoots(w http.ResponseWriter, r *http.Request) {
resp.UserKeys = append(resp.UserKeys, SSHPublicKey{PublicKey: k})
}
- render.JSON(w, r, resp)
+ render.JSON(w, resp)
}
// SSHFederation is an HTTP handler that returns the federated SSH public keys
@@ -383,12 +378,12 @@ func SSHFederation(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
keys, err := mustAuthority(ctx).GetSSHFederation(ctx)
if err != nil {
- render.Error(w, r, errs.InternalServerErr(err))
+ render.Error(w, errs.InternalServerErr(err))
return
}
if len(keys.HostKeys) == 0 && len(keys.UserKeys) == 0 {
- render.Error(w, r, errs.NotFound("no keys found"))
+ render.Error(w, errs.NotFound("no keys found"))
return
}
@@ -400,7 +395,7 @@ func SSHFederation(w http.ResponseWriter, r *http.Request) {
resp.UserKeys = append(resp.UserKeys, SSHPublicKey{PublicKey: k})
}
- render.JSON(w, r, resp)
+ render.JSON(w, resp)
}
// SSHConfig is an HTTP handler that returns rendered templates for ssh clients
@@ -408,18 +403,18 @@ func SSHFederation(w http.ResponseWriter, r *http.Request) {
func SSHConfig(w http.ResponseWriter, r *http.Request) {
var body SSHConfigRequest
if err := read.JSON(r.Body, &body); err != nil {
- render.Error(w, r, errs.BadRequestErr(err, "error reading request body"))
+ render.Error(w, errs.BadRequestErr(err, "error reading request body"))
return
}
if err := body.Validate(); err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
ctx := r.Context()
ts, err := mustAuthority(ctx).GetSSHConfig(ctx, body.Type, body.Data)
if err != nil {
- render.Error(w, r, errs.InternalServerErr(err))
+ render.Error(w, errs.InternalServerErr(err))
return
}
@@ -430,32 +425,32 @@ func SSHConfig(w http.ResponseWriter, r *http.Request) {
case provisioner.SSHHostCert:
cfg.HostTemplates = ts
default:
- render.Error(w, r, errs.InternalServer("it should hot get here"))
+ render.Error(w, errs.InternalServer("it should hot get here"))
return
}
- render.JSON(w, r, cfg)
+ render.JSON(w, cfg)
}
// SSHCheckHost is the HTTP handler that returns if a hosts certificate exists or not.
func SSHCheckHost(w http.ResponseWriter, r *http.Request) {
var body SSHCheckPrincipalRequest
if err := read.JSON(r.Body, &body); err != nil {
- render.Error(w, r, errs.BadRequestErr(err, "error reading request body"))
+ render.Error(w, errs.BadRequestErr(err, "error reading request body"))
return
}
if err := body.Validate(); err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
ctx := r.Context()
exists, err := mustAuthority(ctx).CheckSSHHost(ctx, body.Principal, body.Token)
if err != nil {
- render.Error(w, r, errs.InternalServerErr(err))
+ render.Error(w, errs.InternalServerErr(err))
return
}
- render.JSON(w, r, &SSHCheckPrincipalResponse{
+ render.JSON(w, &SSHCheckPrincipalResponse{
Exists: exists,
})
}
@@ -470,10 +465,10 @@ func SSHGetHosts(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
hosts, err := mustAuthority(ctx).GetSSHHosts(ctx, cert)
if err != nil {
- render.Error(w, r, errs.InternalServerErr(err))
+ render.Error(w, errs.InternalServerErr(err))
return
}
- render.JSON(w, r, &SSHGetHostsResponse{
+ render.JSON(w, &SSHGetHostsResponse{
Hosts: hosts,
})
}
@@ -482,63 +477,35 @@ func SSHGetHosts(w http.ResponseWriter, r *http.Request) {
func SSHBastion(w http.ResponseWriter, r *http.Request) {
var body SSHBastionRequest
if err := read.JSON(r.Body, &body); err != nil {
- render.Error(w, r, errs.BadRequestErr(err, "error reading request body"))
+ render.Error(w, errs.BadRequestErr(err, "error reading request body"))
return
}
if err := body.Validate(); err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
ctx := r.Context()
bastion, err := mustAuthority(ctx).GetSSHBastion(ctx, body.User, body.Hostname)
if err != nil {
- render.Error(w, r, errs.InternalServerErr(err))
+ render.Error(w, errs.InternalServerErr(err))
return
}
- render.JSON(w, r, &SSHBastionResponse{
+ render.JSON(w, &SSHBastionResponse{
Hostname: body.Hostname,
Bastion: bastion,
})
}
-// identityModifier is a custom modifier used to force a fixed duration, and set
-// the identity URI.
+// identityModifier is a custom modifier used to force a fixed duration.
type identityModifier struct {
- Identity *url.URL
NotBefore time.Time
NotAfter time.Time
}
-// Enforce implements the enforcer interface and sets the validity bounds and
-// the identity uri to the certificate.
func (m *identityModifier) Enforce(cert *x509.Certificate) error {
cert.NotBefore = m.NotBefore
cert.NotAfter = m.NotAfter
- if m.Identity != nil {
- var identityURL = m.Identity.String()
- for _, u := range cert.URIs {
- if u.String() == identityURL {
- return nil
- }
- }
- cert.URIs = append(cert.URIs, m.Identity)
- }
-
- return nil
-}
-
-// getIdentityURI returns the first valid UUID URN from the given CSR.
-func getIdentityURI(cr *x509.CertificateRequest) *url.URL {
- for _, u := range cr.URIs {
- s := u.String()
- // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
- if len(s) == 9+36 && strings.EqualFold(s[:9], "urn:uuid:") {
- if _, err := uuid.Parse(s); err == nil {
- return u
- }
- }
- }
return nil
}
diff --git a/vendor/github.com/smallstep/certificates/api/sshRekey.go b/vendor/github.com/smallstep/certificates/api/sshRekey.go
index 0db4d4d..80fc6d8 100644
--- a/vendor/github.com/smallstep/certificates/api/sshRekey.go
+++ b/vendor/github.com/smallstep/certificates/api/sshRekey.go
@@ -42,19 +42,19 @@ type SSHRekeyResponse struct {
func SSHRekey(w http.ResponseWriter, r *http.Request) {
var body SSHRekeyRequest
if err := read.JSON(r.Body, &body); err != nil {
- render.Error(w, r, errs.BadRequestErr(err, "error reading request body"))
+ render.Error(w, errs.BadRequestErr(err, "error reading request body"))
return
}
logOtt(w, body.OTT)
if err := body.Validate(); err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
publicKey, err := ssh.ParsePublicKey(body.PublicKey)
if err != nil {
- render.Error(w, r, errs.BadRequestErr(err, "error parsing publicKey"))
+ render.Error(w, errs.BadRequestErr(err, "error parsing publicKey"))
return
}
@@ -64,18 +64,18 @@ func SSHRekey(w http.ResponseWriter, r *http.Request) {
a := mustAuthority(ctx)
signOpts, err := a.Authorize(ctx, body.OTT)
if err != nil {
- render.Error(w, r, errs.UnauthorizedErr(err))
+ render.Error(w, errs.UnauthorizedErr(err))
return
}
oldCert, _, err := provisioner.ExtractSSHPOPCert(body.OTT)
if err != nil {
- render.Error(w, r, errs.InternalServerErr(err))
+ render.Error(w, errs.InternalServerErr(err))
return
}
newCert, err := a.RekeySSH(ctx, oldCert, publicKey, signOpts...)
if err != nil {
- render.Error(w, r, errs.ForbiddenErr(err, "error rekeying ssh certificate"))
+ render.Error(w, errs.ForbiddenErr(err, "error rekeying ssh certificate"))
return
}
@@ -85,12 +85,12 @@ func SSHRekey(w http.ResponseWriter, r *http.Request) {
identity, err := renewIdentityCertificate(r, notBefore, notAfter)
if err != nil {
- render.Error(w, r, errs.ForbiddenErr(err, "error renewing identity certificate"))
+ render.Error(w, errs.ForbiddenErr(err, "error renewing identity certificate"))
return
}
LogSSHCertificate(w, newCert)
- render.JSONStatus(w, r, &SSHRekeyResponse{
+ render.JSONStatus(w, &SSHRekeyResponse{
Certificate: SSHCertificate{newCert},
IdentityCertificate: identity,
}, http.StatusCreated)
diff --git a/vendor/github.com/smallstep/certificates/api/sshRenew.go b/vendor/github.com/smallstep/certificates/api/sshRenew.go
index dea7cea..cd6d9bd 100644
--- a/vendor/github.com/smallstep/certificates/api/sshRenew.go
+++ b/vendor/github.com/smallstep/certificates/api/sshRenew.go
@@ -40,13 +40,13 @@ type SSHRenewResponse struct {
func SSHRenew(w http.ResponseWriter, r *http.Request) {
var body SSHRenewRequest
if err := read.JSON(r.Body, &body); err != nil {
- render.Error(w, r, errs.BadRequestErr(err, "error reading request body"))
+ render.Error(w, errs.BadRequestErr(err, "error reading request body"))
return
}
logOtt(w, body.OTT)
if err := body.Validate(); err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
@@ -56,18 +56,18 @@ func SSHRenew(w http.ResponseWriter, r *http.Request) {
a := mustAuthority(ctx)
_, err := a.Authorize(ctx, body.OTT)
if err != nil {
- render.Error(w, r, errs.UnauthorizedErr(err))
+ render.Error(w, errs.UnauthorizedErr(err))
return
}
oldCert, _, err := provisioner.ExtractSSHPOPCert(body.OTT)
if err != nil {
- render.Error(w, r, errs.InternalServerErr(err))
+ render.Error(w, errs.InternalServerErr(err))
return
}
newCert, err := a.RenewSSH(ctx, oldCert)
if err != nil {
- render.Error(w, r, errs.ForbiddenErr(err, "error renewing ssh certificate"))
+ render.Error(w, errs.ForbiddenErr(err, "error renewing ssh certificate"))
return
}
@@ -77,12 +77,12 @@ func SSHRenew(w http.ResponseWriter, r *http.Request) {
identity, err := renewIdentityCertificate(r, notBefore, notAfter)
if err != nil {
- render.Error(w, r, errs.ForbiddenErr(err, "error renewing identity certificate"))
+ render.Error(w, errs.ForbiddenErr(err, "error renewing identity certificate"))
return
}
LogSSHCertificate(w, newCert)
- render.JSONStatus(w, r, &SSHSignResponse{
+ render.JSONStatus(w, &SSHSignResponse{
Certificate: SSHCertificate{newCert},
IdentityCertificate: identity,
}, http.StatusCreated)
diff --git a/vendor/github.com/smallstep/certificates/api/sshRevoke.go b/vendor/github.com/smallstep/certificates/api/sshRevoke.go
index 2fe4919..d377def 100644
--- a/vendor/github.com/smallstep/certificates/api/sshRevoke.go
+++ b/vendor/github.com/smallstep/certificates/api/sshRevoke.go
@@ -51,12 +51,12 @@ func (r *SSHRevokeRequest) Validate() (err error) {
func SSHRevoke(w http.ResponseWriter, r *http.Request) {
var body SSHRevokeRequest
if err := read.JSON(r.Body, &body); err != nil {
- render.Error(w, r, errs.BadRequestErr(err, "error reading request body"))
+ render.Error(w, errs.BadRequestErr(err, "error reading request body"))
return
}
if err := body.Validate(); err != nil {
- render.Error(w, r, err)
+ render.Error(w, err)
return
}
@@ -75,18 +75,18 @@ func SSHRevoke(w http.ResponseWriter, r *http.Request) {
logOtt(w, body.OTT)
if _, err := a.Authorize(ctx, body.OTT); err != nil {
- render.Error(w, r, errs.UnauthorizedErr(err))
+ render.Error(w, errs.UnauthorizedErr(err))
return
}
opts.OTT = body.OTT
if err := a.Revoke(ctx, opts); err != nil {
- render.Error(w, r, errs.ForbiddenErr(err, "error revoking ssh certificate"))
+ render.Error(w, errs.ForbiddenErr(err, "error revoking ssh certificate"))
return
}
logSSHRevoke(w, opts)
- render.JSON(w, r, &SSHRevokeResponse{Status: "ok"})
+ render.JSON(w, &SSHRevokeResponse{Status: "ok"})
}
func logSSHRevoke(w http.ResponseWriter, ri *authority.RevokeOptions) {
diff --git a/vendor/github.com/smallstep/certificates/authority/admin/errors.go b/vendor/github.com/smallstep/certificates/authority/admin/errors.go
index a14e2de..c729c8b 100644
--- a/vendor/github.com/smallstep/certificates/authority/admin/errors.go
+++ b/vendor/github.com/smallstep/certificates/authority/admin/errors.go
@@ -205,8 +205,8 @@ func (e *Error) ToLog() (interface{}, error) {
}
// Render implements render.RenderableError for Error.
-func (e *Error) Render(w http.ResponseWriter, r *http.Request) {
+func (e *Error) Render(w http.ResponseWriter) {
e.Message = e.Err.Error()
- render.JSONStatus(w, r, e, e.StatusCode())
+ render.JSONStatus(w, e, e.StatusCode())
}
diff --git a/vendor/github.com/smallstep/certificates/authority/authority.go b/vendor/github.com/smallstep/certificates/authority/authority.go
index 4a91236..d3b9328 100644
--- a/vendor/github.com/smallstep/certificates/authority/authority.go
+++ b/vendor/github.com/smallstep/certificates/authority/authority.go
@@ -49,7 +49,6 @@ type Authority struct {
templates *templates.Templates
linkedCAToken string
webhookClient *http.Client
- httpClient *http.Client
// X509 CA
password []byte
@@ -257,10 +256,7 @@ func (a *Authority) ReloadAdminResources(ctx context.Context) error {
provClxn := provisioner.NewCollection(provisionerConfig.Audiences)
for _, p := range provList {
if err := p.Init(provisionerConfig); err != nil {
- log.Printf("failed to initialize %s provisioner %q: %v\n", p.GetType(), p.GetName(), err)
- p = provisioner.Uninitialized{
- Interface: p, Reason: err,
- }
+ return err
}
if err := provClxn.Store(p); err != nil {
return err
@@ -492,15 +488,6 @@ func (a *Authority) init() error {
a.certificates.Store(hex.EncodeToString(sum[:]), crt)
}
- // Initialize HTTPClient with all root certs
- clientRoots := make([]*x509.Certificate, 0, len(a.rootX509Certs)+len(a.federatedX509Certs))
- clientRoots = append(clientRoots, a.rootX509Certs...)
- clientRoots = append(clientRoots, a.federatedX509Certs...)
- a.httpClient, err = newHTTPClient(clientRoots...)
- if err != nil {
- return err
- }
-
// Decrypt and load SSH keys
var tmplVars templates.Step
if a.config.SSH != nil {
diff --git a/vendor/github.com/smallstep/certificates/authority/authorize.go b/vendor/github.com/smallstep/certificates/authority/authorize.go
index 0a693c6..0214768 100644
--- a/vendor/github.com/smallstep/certificates/authority/authorize.go
+++ b/vendor/github.com/smallstep/certificates/authority/authorize.go
@@ -64,10 +64,6 @@ func (a *Authority) getProvisionerFromToken(token string) (provisioner.Interface
if !ok {
return nil, nil, fmt.Errorf("provisioner not found or invalid audience (%s)", strings.Join(claims.Audience, ", "))
}
- // If the provisioner is disabled, send an appropriate message to the client
- if _, ok := p.(provisioner.Uninitialized); ok {
- return nil, nil, errs.New(http.StatusUnauthorized, "provisioner %q is disabled due to an initialization error", p.GetName())
- }
return p, &claims, nil
}
diff --git a/vendor/github.com/smallstep/certificates/authority/export.go b/vendor/github.com/smallstep/certificates/authority/export.go
index 43479d5..b8efbbd 100644
--- a/vendor/github.com/smallstep/certificates/authority/export.go
+++ b/vendor/github.com/smallstep/certificates/authority/export.go
@@ -8,12 +8,10 @@ import (
"strings"
"github.com/pkg/errors"
- "google.golang.org/protobuf/types/known/structpb"
-
- "github.com/smallstep/cli-utils/step"
- "go.step.sm/linkedca"
-
"github.com/smallstep/certificates/authority/provisioner"
+ "go.step.sm/cli-utils/step"
+ "go.step.sm/linkedca"
+ "google.golang.org/protobuf/types/known/structpb"
)
// Export creates a linkedca configuration form the current ca.json and loaded
diff --git a/vendor/github.com/smallstep/certificates/authority/http_client.go b/vendor/github.com/smallstep/certificates/authority/http_client.go
deleted file mode 100644
index ff61e45..0000000
--- a/vendor/github.com/smallstep/certificates/authority/http_client.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package authority
-
-import (
- "crypto/tls"
- "crypto/x509"
- "fmt"
- "net/http"
-)
-
-// newHTTPClient will return an HTTP client that trusts the system cert pool and
-// the given roots, but only if the http.DefaultTransport is an *http.Transport.
-// If not, it will return the default HTTP client.
-func newHTTPClient(roots ...*x509.Certificate) (*http.Client, error) {
- if tr, ok := http.DefaultTransport.(*http.Transport); ok {
- pool, err := x509.SystemCertPool()
- if err != nil {
- return nil, fmt.Errorf("error initializing http client: %w", err)
- }
- for _, crt := range roots {
- pool.AddCert(crt)
- }
-
- tr = tr.Clone()
- tr.TLSClientConfig = &tls.Config{
- MinVersion: tls.VersionTLS12,
- RootCAs: pool,
- }
- return &http.Client{
- Transport: tr,
- }, nil
- }
-
- return &http.Client{}, nil
-}
diff --git a/vendor/github.com/smallstep/certificates/authority/linkedca.go b/vendor/github.com/smallstep/certificates/authority/linkedca.go
index aa8de3a..3eaa76c 100644
--- a/vendor/github.com/smallstep/certificates/authority/linkedca.go
+++ b/vendor/github.com/smallstep/certificates/authority/linkedca.go
@@ -110,7 +110,7 @@ func newLinkedCAClient(token string) (*linkedCaClient, error) {
tlsConfig.GetClientCertificate = renewer.GetClientCertificate
// Start mTLS client
- conn, err := grpc.NewClient(u.Host, grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)))
+ conn, err := grpc.Dial(u.Host, grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)))
if err != nil {
return nil, errors.Wrapf(err, "error connecting %s", u.Host)
}
@@ -478,7 +478,10 @@ func getAuthority(sans []string) (string, error) {
// getRootCertificate creates an insecure majordomo client and returns the
// verified root certificate.
func getRootCertificate(endpoint, fingerprint string) (*x509.Certificate, error) {
- conn, err := grpc.NewClient(endpoint, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ conn, err := grpc.DialContext(ctx, endpoint, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{
//nolint:gosec // used in bootstrap protocol
InsecureSkipVerify: true, // lgtm[go/disabled-certificate-check]
})))
@@ -486,7 +489,7 @@ func getRootCertificate(endpoint, fingerprint string) (*x509.Certificate, error)
return nil, errors.Wrapf(err, "error connecting %s", endpoint)
}
- ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
+ ctx, cancel = context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
client := linkedca.NewMajordomoClient(conn)
@@ -528,7 +531,11 @@ func getRootCertificate(endpoint, fingerprint string) (*x509.Certificate, error)
// login creates a new majordomo client with just the root ca pool and returns
// the signed certificate and tls configuration.
func login(authority, token string, csr *x509.CertificateRequest, signer crypto.PrivateKey, endpoint string, rootCAs *x509.CertPool) (*tls.Certificate, *tls.Config, error) {
- conn, err := grpc.NewClient(endpoint, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{
+ // Connect to majordomo
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ conn, err := grpc.DialContext(ctx, endpoint, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{
MinVersion: tls.VersionTLS12,
RootCAs: rootCAs,
})))
@@ -537,7 +544,7 @@ func login(authority, token string, csr *x509.CertificateRequest, signer crypto.
}
// Login to get the signed certificate
- ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
+ ctx, cancel = context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
client := linkedca.NewMajordomoClient(conn)
diff --git a/vendor/github.com/smallstep/certificates/authority/policy/engine.go b/vendor/github.com/smallstep/certificates/authority/policy/engine.go
index 475522d..d3881d9 100644
--- a/vendor/github.com/smallstep/certificates/authority/policy/engine.go
+++ b/vendor/github.com/smallstep/certificates/authority/policy/engine.go
@@ -91,7 +91,7 @@ func (e *Engine) IsSSHCertificateAllowed(cert *ssh.Certificate) error {
// when no host policy engine is configured, but a user policy engine is
// configured, the host certificate is denied.
if e.sshHostPolicy == nil && e.sshUserPolicy != nil {
- return errors.New("authority not allowed to sign SSH host certificates when SSH user certificate policy is active")
+ return errors.New("authority not allowed to sign ssh host certificates")
}
// return result of SSH host policy evaluation
@@ -100,12 +100,12 @@ func (e *Engine) IsSSHCertificateAllowed(cert *ssh.Certificate) error {
// when no user policy engine is configured, but a host policy engine is
// configured, the user certificate is denied.
if e.sshUserPolicy == nil && e.sshHostPolicy != nil {
- return errors.New("authority not allowed to sign SSH user certificates when SSH host certificate policy is active")
+ return errors.New("authority not allowed to sign ssh user certificates")
}
// return result of SSH user policy evaluation
return e.sshUserPolicy.IsSSHCertificateAllowed(cert)
default:
- return fmt.Errorf("unexpected SSH certificate type %q", cert.CertType)
+ return fmt.Errorf("unexpected ssh certificate type %q", cert.CertType)
}
}
diff --git a/vendor/github.com/smallstep/certificates/authority/policy/policy.go b/vendor/github.com/smallstep/certificates/authority/policy/policy.go
index 1da45e8..96c7d7e 100644
--- a/vendor/github.com/smallstep/certificates/authority/policy/policy.go
+++ b/vendor/github.com/smallstep/certificates/authority/policy/policy.go
@@ -21,7 +21,6 @@ type HostPolicy policy.SSHNamePolicyEngine
func NewX509PolicyEngine(policyOptions X509PolicyOptionsInterface) (X509Policy, error) {
// return early if no policy engine options to configure
if policyOptions == nil {
- //nolint:nilnil,nolintlint // expected values
return nil, nil
}
@@ -51,7 +50,6 @@ func NewX509PolicyEngine(policyOptions X509PolicyOptionsInterface) (X509Policy,
// ensure no policy engine is returned when no name options were provided
if len(options) == 0 {
- //nolint:nilnil,nolintlint // expected values
return nil, nil
}
@@ -95,7 +93,6 @@ func NewSSHHostPolicyEngine(policyOptions SSHPolicyOptionsInterface) (HostPolicy
func newSSHPolicyEngine(policyOptions SSHPolicyOptionsInterface, typ sshPolicyEngineType) (policy.SSHNamePolicyEngine, error) {
// return early if no policy engine options to configure
if policyOptions == nil {
- //nolint:nilnil,nolintlint // expected values
return nil, nil
}
@@ -137,7 +134,6 @@ func newSSHPolicyEngine(policyOptions SSHPolicyOptionsInterface, typ sshPolicyEn
// ensure no policy engine is returned when no name options were provided
if len(options) == 0 {
- //nolint:nilnil,nolintlint // expected values
return nil, nil
}
diff --git a/vendor/github.com/smallstep/certificates/authority/provisioner/acme.go b/vendor/github.com/smallstep/certificates/authority/provisioner/acme.go
index 3b7fa65..96f37d5 100644
--- a/vendor/github.com/smallstep/certificates/authority/provisioner/acme.go
+++ b/vendor/github.com/smallstep/certificates/authority/provisioner/acme.go
@@ -10,7 +10,6 @@ import (
"time"
"github.com/pkg/errors"
- "github.com/smallstep/certificates/acme/wire"
"go.step.sm/linkedca"
)
@@ -27,10 +26,6 @@ const (
TLS_ALPN_01 ACMEChallenge = "tls-alpn-01"
// DEVICE_ATTEST_01 is the device-attest-01 ACME challenge.
DEVICE_ATTEST_01 ACMEChallenge = "device-attest-01"
- // WIREOIDC_01 is the Wire OIDC challenge.
- WIREOIDC_01 ACMEChallenge = "wire-oidc-01"
- // WIREDPOP_01 is the Wire DPoP challenge.
- WIREDPOP_01 ACMEChallenge = "wire-dpop-01"
)
// String returns a normalized version of the challenge.
@@ -41,7 +36,7 @@ func (c ACMEChallenge) String() string {
// Validate returns an error if the acme challenge is not a valid one.
func (c ACMEChallenge) Validate() error {
switch ACMEChallenge(c.String()) {
- case HTTP_01, DNS_01, TLS_ALPN_01, DEVICE_ATTEST_01, WIREOIDC_01, WIREDPOP_01:
+ case HTTP_01, DNS_01, TLS_ALPN_01, DEVICE_ATTEST_01:
return nil
default:
return fmt.Errorf("acme challenge %q is not supported", c)
@@ -107,8 +102,7 @@ type ACME struct {
RequireEAB bool `json:"requireEAB,omitempty"`
// Challenges contains the enabled challenges for this provisioner. If this
// value is not set the default http-01, dns-01 and tls-alpn-01 challenges
- // will be enabled, device-attest-01, wire-oidc-01 and wire-dpop-01 will be
- // disabled.
+ // will be enabled, device-attest-01 will be disabled.
Challenges []ACMEChallenge `json:"challenges,omitempty"`
// AttestationFormats contains the enabled attestation formats for this
// provisioner. If this value is not set the default apple, step and tpm
@@ -212,50 +206,10 @@ func (p *ACME) Init(config Config) (err error) {
}
}
- if err := p.initializeWireOptions(); err != nil {
- return fmt.Errorf("failed initializing Wire options: %w", err)
- }
-
p.ctl, err = NewController(p, p.Claims, config, p.Options)
return
}
-// initializeWireOptions initializes the options for the ACME Wire
-// integration. It'll return early if no Wire challenge types are
-// enabled.
-func (p *ACME) initializeWireOptions() error {
- hasWireChallenges := false
- for _, c := range p.Challenges {
- if c == WIREOIDC_01 || c == WIREDPOP_01 {
- hasWireChallenges = true
- break
- }
- }
- if !hasWireChallenges {
- return nil
- }
-
- w, err := p.GetOptions().GetWireOptions()
- if err != nil {
- return fmt.Errorf("failed getting Wire options: %w", err)
- }
-
- if err := w.Validate(); err != nil {
- return fmt.Errorf("failed validating Wire options: %w", err)
- }
-
- // at this point the Wire options have been validated, and (mostly)
- // initialized. Remote keys will be loaded upon the first verification,
- // currently.
- // TODO(hs): can/should we "prime" the underlying remote keyset, to verify
- // auto discovery works as expected? Because of the current way provisioners
- // are initialized, doing that as part of the initialization isn't the best
- // time to do it, because it could result in operations not resulting in the
- // expected result in all cases.
-
- return nil
-}
-
// ACMEIdentifierType encodes ACME Identifier types
type ACMEIdentifierType string
@@ -264,10 +218,6 @@ const (
IP ACMEIdentifierType = "ip"
// DNS is the ACME dns identifier type
DNS ACMEIdentifierType = "dns"
- // WireUser is the Wire user identifier type
- WireUser ACMEIdentifierType = "wireapp-user"
- // WireDevice is the Wire device identifier type
- WireDevice ACMEIdentifierType = "wireapp-device"
)
// ACMEIdentifier encodes ACME Order Identifiers
@@ -293,18 +243,6 @@ func (p *ACME) AuthorizeOrderIdentifier(_ context.Context, identifier ACMEIdenti
err = x509Policy.IsIPAllowed(net.ParseIP(identifier.Value))
case DNS:
err = x509Policy.IsDNSAllowed(identifier.Value)
- case WireUser:
- var wireID wire.UserID
- if wireID, err = wire.ParseUserID(identifier.Value); err != nil {
- return fmt.Errorf("failed parsing Wire SANs: %w", err)
- }
- err = x509Policy.AreSANsAllowed([]string{wireID.Handle})
- case WireDevice:
- var wireID wire.DeviceID
- if wireID, err = wire.ParseDeviceID(identifier.Value); err != nil {
- return fmt.Errorf("failed parsing Wire SANs: %w", err)
- }
- err = x509Policy.AreSANsAllowed([]string{wireID.ClientID})
default:
err = fmt.Errorf("invalid ACME identifier type '%s' provided", identifier.Type)
}
diff --git a/vendor/github.com/smallstep/certificates/authority/provisioner/aws.go b/vendor/github.com/smallstep/certificates/authority/provisioner/aws.go
index 9e1d9b7..e95feed 100644
--- a/vendor/github.com/smallstep/certificates/authority/provisioner/aws.go
+++ b/vendor/github.com/smallstep/certificates/authority/provisioner/aws.go
@@ -358,7 +358,7 @@ func (p *AWS) AuthorizeSign(ctx context.Context, token string) ([]SignOption, er
if p.DisableCustomSANs {
dnsName := fmt.Sprintf("ip-%s.%s.compute.internal", strings.ReplaceAll(doc.PrivateIP, ".", "-"), doc.Region)
so = append(so,
- dnsNamesSubsetValidator([]string{dnsName}),
+ dnsNamesValidator([]string{dnsName}),
ipAddressesValidator([]net.IP{
net.ParseIP(doc.PrivateIP),
}),
diff --git a/vendor/github.com/smallstep/certificates/authority/provisioner/aws_certificates.pem b/vendor/github.com/smallstep/certificates/authority/provisioner/aws_certificates.pem
index 167007f..994758b 100644
--- a/vendor/github.com/smallstep/certificates/authority/provisioner/aws_certificates.pem
+++ b/vendor/github.com/smallstep/certificates/authority/provisioner/aws_certificates.pem
@@ -1,89 +1,25 @@
# https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/verify-signature.html
# https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/regions-certs.html use RSA format
-
-# certificate for us-east-2
------BEGIN CERTIFICATE-----
-MIIDITCCAoqgAwIBAgIUVJTc+hOU+8Gk3JlqsX438Dk5c58wDQYJKoZIhvcNAQEL
-BQAwXDELMAkGA1UEBhMCVVMxGTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAO
-BgNVBAcTB1NlYXR0bGUxIDAeBgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExD
-MB4XDTI0MDQyOTE3MTE0OVoXDTI5MDQyODE3MTE0OVowXDELMAkGA1UEBhMCVVMx
-GTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAOBgNVBAcTB1NlYXR0bGUxIDAe
-BgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExDMIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQCHvRjf/0kStpJ248khtIaN8qkDN3tkw4VjvA9nvPl2anJO+eIB
-UqPfQG09kZlwpWpmyO8bGB2RWqWxCwuB/dcnIob6w420k9WY5C0IIGtDRNauN3ku
-vGXkw3HEnF0EjYr0pcyWUvByWY4KswZV42X7Y7XSS13hOIcL6NLA+H94/QIDAQAB
-o4HfMIHcMAsGA1UdDwQEAwIHgDAdBgNVHQ4EFgQUJdbMCBXKtvCcWdwUUizvtUF2
-UTgwgZkGA1UdIwSBkTCBjoAUJdbMCBXKtvCcWdwUUizvtUF2UTihYKReMFwxCzAJ
-BgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdT
-ZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQ4IUVJTc+hOU
-+8Gk3JlqsX438Dk5c58wEgYDVR0TAQH/BAgwBgEB/wIBADANBgkqhkiG9w0BAQsF
-AAOBgQAywJQaVNWJqW0R0T0xVOSoN1GLk9x9kKEuN67RN9CLin4dA97qa7Mr5W4P
-FZ6vnh5CjOhQBRXV9xJUeYSdqVItNAUFK/fEzDdjf1nUfPlQ3OJ49u6CV01NoJ9m
-usvY9kWcV46dqn2bk2MyfTTgvmeqP8fiMRPxxnVRkSzlldP5Fg==
------END CERTIFICATE-----
-
-# certificate for us-east-1
------BEGIN CERTIFICATE-----
-MIIDITCCAoqgAwIBAgIUE1y2NIKCU+Rg4uu4u32koG9QEYIwDQYJKoZIhvcNAQEL
-BQAwXDELMAkGA1UEBhMCVVMxGTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAO
-BgNVBAcTB1NlYXR0bGUxIDAeBgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExD
-MB4XDTI0MDQyOTE3MzQwMVoXDTI5MDQyODE3MzQwMVowXDELMAkGA1UEBhMCVVMx
-GTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAOBgNVBAcTB1NlYXR0bGUxIDAe
-BgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExDMIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQCHvRjf/0kStpJ248khtIaN8qkDN3tkw4VjvA9nvPl2anJO+eIB
-UqPfQG09kZlwpWpmyO8bGB2RWqWxCwuB/dcnIob6w420k9WY5C0IIGtDRNauN3ku
-vGXkw3HEnF0EjYr0pcyWUvByWY4KswZV42X7Y7XSS13hOIcL6NLA+H94/QIDAQAB
-o4HfMIHcMAsGA1UdDwQEAwIHgDAdBgNVHQ4EFgQUJdbMCBXKtvCcWdwUUizvtUF2
-UTgwgZkGA1UdIwSBkTCBjoAUJdbMCBXKtvCcWdwUUizvtUF2UTihYKReMFwxCzAJ
-BgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdT
-ZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQ4IUE1y2NIKC
-U+Rg4uu4u32koG9QEYIwEgYDVR0TAQH/BAgwBgEB/wIBADANBgkqhkiG9w0BAQsF
-AAOBgQAlxSmwcWnhT4uAeSinJuz+1BTcKhVSWb5jT8pYjQb8ZoZkXXRGb09mvYeU
-NeqOBr27rvRAnaQ/9LUQf72+SahDFuS4CMI8nwowytqbmwquqFr4dxA/SDADyRiF
-ea1UoMuNHTY49J/1vPomqsVn7mugTp+TbjqCfOJTpu0temHcFA==
------END CERTIFICATE-----
-
-# certificate for us-west-1
------BEGIN CERTIFICATE-----
-MIIDITCCAoqgAwIBAgIUK2zmY9PUSTR7rc1k2OwPYu4+g7wwDQYJKoZIhvcNAQEL
-BQAwXDELMAkGA1UEBhMCVVMxGTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAO
-BgNVBAcTB1NlYXR0bGUxIDAeBgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExD
-MB4XDTI0MDQyOTE3MDI0M1oXDTI5MDQyODE3MDI0M1owXDELMAkGA1UEBhMCVVMx
-GTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAOBgNVBAcTB1NlYXR0bGUxIDAe
-BgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExDMIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQCHvRjf/0kStpJ248khtIaN8qkDN3tkw4VjvA9nvPl2anJO+eIB
-UqPfQG09kZlwpWpmyO8bGB2RWqWxCwuB/dcnIob6w420k9WY5C0IIGtDRNauN3ku
-vGXkw3HEnF0EjYr0pcyWUvByWY4KswZV42X7Y7XSS13hOIcL6NLA+H94/QIDAQAB
-o4HfMIHcMAsGA1UdDwQEAwIHgDAdBgNVHQ4EFgQUJdbMCBXKtvCcWdwUUizvtUF2
-UTgwgZkGA1UdIwSBkTCBjoAUJdbMCBXKtvCcWdwUUizvtUF2UTihYKReMFwxCzAJ
-BgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdT
-ZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQ4IUK2zmY9PU
-STR7rc1k2OwPYu4+g7wwEgYDVR0TAQH/BAgwBgEB/wIBADANBgkqhkiG9w0BAQsF
-AAOBgQA1Ng4QmN4n7iPh5CnadSOc0ZfM7by0dBePwZJyGvOHdaw6P6E/vEk76KsC
-Q8p+akuzVzVPkU4kBK/TRqLp19wEWoVwhhTaxHjQ1tTRHqXIVlrkw4JrtFbeNM21
-GlkSLonuzmNZdivn9WuQYeGe7nUD4w3q9GgiF3CPorJe+UxtbA==
------END CERTIFICATE-----
-
-# certificate for us-west-2
------BEGIN CERTIFICATE-----
-MIIDITCCAoqgAwIBAgIUFx8PxCkbHwpD31bOyCtyz3GclbgwDQYJKoZIhvcNAQEL
-BQAwXDELMAkGA1UEBhMCVVMxGTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAO
-BgNVBAcTB1NlYXR0bGUxIDAeBgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExD
-MB4XDTI0MDQyOTE3MjM1OVoXDTI5MDQyODE3MjM1OVowXDELMAkGA1UEBhMCVVMx
-GTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAOBgNVBAcTB1NlYXR0bGUxIDAe
-BgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExDMIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQCHvRjf/0kStpJ248khtIaN8qkDN3tkw4VjvA9nvPl2anJO+eIB
-UqPfQG09kZlwpWpmyO8bGB2RWqWxCwuB/dcnIob6w420k9WY5C0IIGtDRNauN3ku
-vGXkw3HEnF0EjYr0pcyWUvByWY4KswZV42X7Y7XSS13hOIcL6NLA+H94/QIDAQAB
-o4HfMIHcMAsGA1UdDwQEAwIHgDAdBgNVHQ4EFgQUJdbMCBXKtvCcWdwUUizvtUF2
-UTgwgZkGA1UdIwSBkTCBjoAUJdbMCBXKtvCcWdwUUizvtUF2UTihYKReMFwxCzAJ
-BgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdT
-ZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQ4IUFx8PxCkb
-HwpD31bOyCtyz3GclbgwEgYDVR0TAQH/BAgwBgEB/wIBADANBgkqhkiG9w0BAQsF
-AAOBgQBzOl+9Xy1+UsbUBI95HO9mbbdnuX+aMJXgG9uFZNjgNEbMcvx+h8P9IMko
-z7PzFdheQQ1NLjsHH9mSR1SyC4m9ja6BsejH5nLBWyCdjfdP3muZM4O5+r7vUa1O
-dWU+hP/T7DUrPAIVMOE7mpYa+WPWJrN6BlRwQkKQ7twm9kDalA==
+# default certificate for "other regions"
+-----BEGIN CERTIFICATE-----
+MIIDIjCCAougAwIBAgIJAKnL4UEDMN/FMA0GCSqGSIb3DQEBBQUAMGoxCzAJBgNV
+BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdTZWF0dGxlMRgw
+FgYDVQQKEw9BbWF6b24uY29tIEluYy4xGjAYBgNVBAMTEWVjMi5hbWF6b25hd3Mu
+Y29tMB4XDTE0MDYwNTE0MjgwMloXDTI0MDYwNTE0MjgwMlowajELMAkGA1UEBhMC
+VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1NlYXR0bGUxGDAWBgNV
+BAoTD0FtYXpvbi5jb20gSW5jLjEaMBgGA1UEAxMRZWMyLmFtYXpvbmF3cy5jb20w
+gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIe9GN//SRK2knbjySG0ho3yqQM3
+e2TDhWO8D2e8+XZqck754gFSo99AbT2RmXClambI7xsYHZFapbELC4H91ycihvrD
+jbST1ZjkLQgga0NE1q43eS68ZeTDccScXQSNivSlzJZS8HJZjgqzBlXjZftjtdJL
+XeE4hwvo0sD4f3j9AgMBAAGjgc8wgcwwHQYDVR0OBBYEFCXWzAgVyrbwnFncFFIs
+77VBdlE4MIGcBgNVHSMEgZQwgZGAFCXWzAgVyrbwnFncFFIs77VBdlE4oW6kbDBq
+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHU2Vh
+dHRsZTEYMBYGA1UEChMPQW1hem9uLmNvbSBJbmMuMRowGAYDVQQDExFlYzIuYW1h
+em9uYXdzLmNvbYIJAKnL4UEDMN/FMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEF
+BQADgYEAFYcz1OgEhQBXIwIdsgCOS8vEtiJYF+j9uO6jz7VOmJqO+pRlAbRlvY8T
+C1haGgSI/A1uZUKs/Zfnph0oEI0/hu1IIJ/SKBDtN5lvmZ/IzbOPIJWirlsllQIQ
+7zvWbGd9c9+Rm3p04oTvhup99la7kZqevJK0QRdD/6NpCKsqP/0=
-----END CERTIFICATE-----
# certificate for eu-south-1
@@ -157,7 +93,7 @@ NTpxxcXmUKquX+pHmIkK1LKDO8rNE84jqxrxRsfDi6by82fjVYf2pgjJW8R1FAw+
mL5WQRFexbfB5aXhcMo0AA==
-----END CERTIFICATE-----
-# certificate for cn-north-1
+# certificate for cn-north-1, cn-northwest-1
-----BEGIN CERTIFICATE-----
MIIDCzCCAnSgAwIBAgIJALSOMbOoU2svMA0GCSqGSIb3DQEBCwUAMFwxCzAJBgNV
BAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdTZWF0
@@ -178,48 +114,6 @@ oADS0ph+YUz5P/bUCm61wFjlxaTfwKcuTR3ytj7bFLoW5Bm7Sa+TCl3lOGb2taon
SUDlRyNy1jJFstEZjOhs
-----END CERTIFICATE-----
-# certificate for cn-northwest-1
------BEGIN CERTIFICATE-----
-MIIDCzCCAnSgAwIBAgIJALSOMbOoU2svMA0GCSqGSIb3DQEBCwUAMFwxCzAJBgNV
-BAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdTZWF0
-dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQzAeFw0yMzA3MDQw
-ODM1MzlaFw0yODA3MDIwODM1MzlaMFwxCzAJBgNVBAYTAlVTMRkwFwYDVQQIExBX
-YXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdTZWF0dGxlMSAwHgYDVQQKExdBbWF6
-b24gV2ViIFNlcnZpY2VzIExMQzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
-uhhUNlqAZdcWWB/OSDVDGk3OA99EFzOn/mJlmciQ/Xwu2dFJWmSCqEAE6gjufCjQ
-q3voxAhC2CF+elKtJW/C0Sz/LYo60PUqd6iXF4h+upB9HkOOGuWHXsHBTsvgkgGA
-1CGgel4U0Cdq+23eANr8N8m28UzljjSnTlrYCHtzN4sCAwEAAaOB1DCB0TALBgNV
-HQ8EBAMCB4AwHQYDVR0OBBYEFBkZu3wT27NnYgrfH+xJz4HJaNJoMIGOBgNVHSME
-gYYwgYOAFBkZu3wT27NnYgrfH+xJz4HJaNJooWCkXjBcMQswCQYDVQQGEwJVUzEZ
-MBcGA1UECBMQV2FzaGluZ3RvbiBTdGF0ZTEQMA4GA1UEBxMHU2VhdHRsZTEgMB4G
-A1UEChMXQW1hem9uIFdlYiBTZXJ2aWNlcyBMTEOCCQC0jjGzqFNrLzASBgNVHRMB
-Af8ECDAGAQH/AgEAMA0GCSqGSIb3DQEBCwUAA4GBAECji43p+oPkYqmzll7e8Hgb
-oADS0ph+YUz5P/bUCm61wFjlxaTfwKcuTR3ytj7bFLoW5Bm7Sa+TCl3lOGb2taon
-2h+9NirRK6JYk87LMNvbS40HGPFumJL2NzEsGUeK+MRiWu+Oh5/lJGii3qw4YByx
-SUDlRyNy1jJFstEZjOhs
------END CERTIFICATE-----
-
-# certificate for eu-central-1
------BEGIN CERTIFICATE-----
-MIIDITCCAoqgAwIBAgIUFD5GsmkxRuecttwsCG763m3u63UwDQYJKoZIhvcNAQEL
-BQAwXDELMAkGA1UEBhMCVVMxGTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAO
-BgNVBAcTB1NlYXR0bGUxIDAeBgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExD
-MB4XDTI0MDQyOTE1NTUyOVoXDTI5MDQyODE1NTUyOVowXDELMAkGA1UEBhMCVVMx
-GTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAOBgNVBAcTB1NlYXR0bGUxIDAe
-BgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExDMIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQCHvRjf/0kStpJ248khtIaN8qkDN3tkw4VjvA9nvPl2anJO+eIB
-UqPfQG09kZlwpWpmyO8bGB2RWqWxCwuB/dcnIob6w420k9WY5C0IIGtDRNauN3ku
-vGXkw3HEnF0EjYr0pcyWUvByWY4KswZV42X7Y7XSS13hOIcL6NLA+H94/QIDAQAB
-o4HfMIHcMAsGA1UdDwQEAwIHgDAdBgNVHQ4EFgQUJdbMCBXKtvCcWdwUUizvtUF2
-UTgwgZkGA1UdIwSBkTCBjoAUJdbMCBXKtvCcWdwUUizvtUF2UTihYKReMFwxCzAJ
-BgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdT
-ZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQ4IUFD5Gsmkx
-RuecttwsCG763m3u63UwEgYDVR0TAQH/BAgwBgEB/wIBADANBgkqhkiG9w0BAQsF
-AAOBgQBBh0WaXlBsW56Hqk588MmJxsOrvcKfDjF57RgEDgnGnQaJcStCVWDO9UYO
-JX2tdsPw+E7AjDqjsuxYaotLn3Mr3mK0sNOXq9BljBnWD4pARg89KZnZI8FN35HQ
-O/LYOVHCknuPL123VmVRNs51qQA9hkPjvw21UzpDLxaUxt9Z/w==
------END CERTIFICATE-----
-
# certificate for eu-central-2
-----BEGIN CERTIFICATE-----
MIICMzCCAZygAwIBAgIGAXjSGFGiMA0GCSqGSIb3DQEBBQUAMFwxCzAJBgNVBAYT
@@ -236,27 +130,6 @@ NBElvPCDKFvTJl4QQhToy056llO5GvdS9RK+H8xrP2mrqngApoKTApv93vHBixgF
Sn5KrczRO0YSm3OjkqbydU7DFlmkXXR7GYE+5jbHvQHYiT1J5sMu
-----END CERTIFICATE-----
-# certificate for ap-south-1
------BEGIN CERTIFICATE-----
-MIIDITCCAoqgAwIBAgIUDLA+x6tTAP3LRTr0z6nOxfsozdMwDQYJKoZIhvcNAQEL
-BQAwXDELMAkGA1UEBhMCVVMxGTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAO
-BgNVBAcTB1NlYXR0bGUxIDAeBgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExD
-MB4XDTI0MDQyOTE0MTMwMVoXDTI5MDQyODE0MTMwMVowXDELMAkGA1UEBhMCVVMx
-GTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAOBgNVBAcTB1NlYXR0bGUxIDAe
-BgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExDMIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQCHvRjf/0kStpJ248khtIaN8qkDN3tkw4VjvA9nvPl2anJO+eIB
-UqPfQG09kZlwpWpmyO8bGB2RWqWxCwuB/dcnIob6w420k9WY5C0IIGtDRNauN3ku
-vGXkw3HEnF0EjYr0pcyWUvByWY4KswZV42X7Y7XSS13hOIcL6NLA+H94/QIDAQAB
-o4HfMIHcMAsGA1UdDwQEAwIHgDAdBgNVHQ4EFgQUJdbMCBXKtvCcWdwUUizvtUF2
-UTgwgZkGA1UdIwSBkTCBjoAUJdbMCBXKtvCcWdwUUizvtUF2UTihYKReMFwxCzAJ
-BgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdT
-ZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQ4IUDLA+x6tT
-AP3LRTr0z6nOxfsozdMwEgYDVR0TAQH/BAgwBgEB/wIBADANBgkqhkiG9w0BAQsF
-AAOBgQAZ7rYKoAwwiiH1M5GJbrT/BEk3OO2VrEPw8ZxgpqQ/EKlzMlOs/0Cyrmp7
-UYyUgYFQe5nq37Z94rOUSeMgv/WRxaMwrLlLqD78cuF9DSkXaZIX/kECtVaUnjk8
-BZx0QhoIHOpQocJUSlm/dLeMuE0+0A3HNR6JVktGsUdv9ulmKw==
------END CERTIFICATE-----
-
# certificate for ap-south-2
-----BEGIN CERTIFICATE-----
MIICMzCCAZygAwIBAgIGAXjwLj9CMA0GCSqGSIb3DQEBBQUAMFwxCzAJBgNVBAYT
@@ -273,48 +146,6 @@ ETwUZ9mTq2vxlV0KvuetCDNS5u4cJsxe/TGGbYP0yP2qfMl0cCImzRI5W0gn8gog
dervfeT7nH5ih0TWEy/QDWfkQ601L4erm4yh4YQq8vcqAPSkf04N
-----END CERTIFICATE-----
-# certificate for ap-southeast-1
------BEGIN CERTIFICATE-----
-MIIDITCCAoqgAwIBAgIUSqP6ih+++5KF07NXngrWf26mhSUwDQYJKoZIhvcNAQEL
-BQAwXDELMAkGA1UEBhMCVVMxGTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAO
-BgNVBAcTB1NlYXR0bGUxIDAeBgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExD
-MB4XDTI0MDQyOTE0MzAxNFoXDTI5MDQyODE0MzAxNFowXDELMAkGA1UEBhMCVVMx
-GTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAOBgNVBAcTB1NlYXR0bGUxIDAe
-BgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExDMIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQCHvRjf/0kStpJ248khtIaN8qkDN3tkw4VjvA9nvPl2anJO+eIB
-UqPfQG09kZlwpWpmyO8bGB2RWqWxCwuB/dcnIob6w420k9WY5C0IIGtDRNauN3ku
-vGXkw3HEnF0EjYr0pcyWUvByWY4KswZV42X7Y7XSS13hOIcL6NLA+H94/QIDAQAB
-o4HfMIHcMAsGA1UdDwQEAwIHgDAdBgNVHQ4EFgQUJdbMCBXKtvCcWdwUUizvtUF2
-UTgwgZkGA1UdIwSBkTCBjoAUJdbMCBXKtvCcWdwUUizvtUF2UTihYKReMFwxCzAJ
-BgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdT
-ZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQ4IUSqP6ih++
-+5KF07NXngrWf26mhSUwEgYDVR0TAQH/BAgwBgEB/wIBADANBgkqhkiG9w0BAQsF
-AAOBgQAw13BxW11U/JL58j//Fmk7qqtrZTqXmaz1qm2WlIpJpW750MOcP4ux1uPy
-eM0RdVZ4jHSMv5gtLAv/PjExBfw9n6vNCk+5GZG4Xec5DoapBZHXmfMo93sjxBFP
-4x9rWn0GuwAVO9ukjYPevq2Rerilrq5VvppHtbATVNY2qecXDA==
------END CERTIFICATE-----
-
-# certificate for ap-southeast-2
------BEGIN CERTIFICATE-----
-MIIDITCCAoqgAwIBAgIUFxWyAdk4oiXIOC9PxcgjYYh71mwwDQYJKoZIhvcNAQEL
-BQAwXDELMAkGA1UEBhMCVVMxGTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAO
-BgNVBAcTB1NlYXR0bGUxIDAeBgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExD
-MB4XDTI0MDQyOTE1MjE0M1oXDTI5MDQyODE1MjE0M1owXDELMAkGA1UEBhMCVVMx
-GTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAOBgNVBAcTB1NlYXR0bGUxIDAe
-BgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExDMIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQCHvRjf/0kStpJ248khtIaN8qkDN3tkw4VjvA9nvPl2anJO+eIB
-UqPfQG09kZlwpWpmyO8bGB2RWqWxCwuB/dcnIob6w420k9WY5C0IIGtDRNauN3ku
-vGXkw3HEnF0EjYr0pcyWUvByWY4KswZV42X7Y7XSS13hOIcL6NLA+H94/QIDAQAB
-o4HfMIHcMAsGA1UdDwQEAwIHgDAdBgNVHQ4EFgQUJdbMCBXKtvCcWdwUUizvtUF2
-UTgwgZkGA1UdIwSBkTCBjoAUJdbMCBXKtvCcWdwUUizvtUF2UTihYKReMFwxCzAJ
-BgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdT
-ZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQ4IUFxWyAdk4
-oiXIOC9PxcgjYYh71mwwEgYDVR0TAQH/BAgwBgEB/wIBADANBgkqhkiG9w0BAQsF
-AAOBgQByjeQe6lr7fiIhoGdjBXYzDfkX0lGGvMIhRh57G1bbceQfaYdZd7Ptc0jl
-bpycKGaTvhUdkpMOiV2Hi9dOOYawkdhyJDstmDNKu6P9+b6Kak8He5z3NU1tUR2Y
-uTwcz7Ye8Nldx//ws3raErfTI7D6s9m63OX8cAJ/f8bNgikwpw==
------END CERTIFICATE-----
-
# certificate for ap-southeast-3
-----BEGIN CERTIFICATE-----
MIICMzCCAZygAwIBAgIGAXbVDG2yMA0GCSqGSIb3DQEBBQUAMFwxCzAJBgNVBAYT
@@ -395,46 +226,25 @@ WX00FTEj4hRVjameE1nENoO8Z7fUVloAFDlDo69fhkJeSvn51D1WRrPnoWGgEfr1
+OfK1bAcKTtfkkkP9r4RdwSjKzO5Zu/B+Wqm3kVEz/QNcz6npmA6
-----END CERTIFICATE-----
-# certificate for us-gov-east-1
------BEGIN CERTIFICATE-----
-MIIDITCCAoqgAwIBAgIULVyrqjjwZ461qelPCiShB1KCCj4wDQYJKoZIhvcNAQEL
-BQAwXDELMAkGA1UEBhMCVVMxGTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAO
-BgNVBAcTB1NlYXR0bGUxIDAeBgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExD
-MB4XDTI0MDUwNzE1MjIzNloXDTI5MDUwNjE1MjIzNlowXDELMAkGA1UEBhMCVVMx
-GTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAOBgNVBAcTB1NlYXR0bGUxIDAe
-BgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExDMIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQCpohwYUVPH9I7Vbkb3WMe/JB0Y/bmfVj3VpcK445YBRO9K80al
-esjgBc2tAX4KYg4Lht4EBKccLHTzaNi51YEGX1aLNrSmxhz1+WtzNLNUsyY3zD9z
-vwX/3k1+JB2dRA+m+Cpwx4mjzZyAeQtHtegVaAytkmqtxQrSCexBxvqRqQIDAQAB
-o4HfMIHcMAsGA1UdDwQEAwIHgDAdBgNVHQ4EFgQU1ZXneBYnPvYXkHVlVjg7918V
-gE8wgZkGA1UdIwSBkTCBjoAU1ZXneBYnPvYXkHVlVjg7918VgE+hYKReMFwxCzAJ
-BgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdT
-ZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQ4IULVyrqjjw
-Z461qelPCiShB1KCCj4wEgYDVR0TAQH/BAgwBgEB/wIBADANBgkqhkiG9w0BAQsF
-AAOBgQBfAL/YZv0y3zmVbXjyxQCsDloeDCJjFKIu3ameEckeIWJbST9LMto0zViZ
-puIAf05x6GQiEqfBMk+YMxJfcTmJB4Ebaj4egFlslJPSHyC2xuydHlr3B04INOH5
-Z2oCM68u6GGbj0jZjg7GJonkReG9N72kDva/ukwZKgq8zErQVQ==
------END CERTIFICATE-----
-
-# certificate for us-gov-west-1
+# certificate for us-gov-east-1 and us-gov-west-1
-----BEGIN CERTIFICATE-----
-MIIDITCCAoqgAwIBAgIUe5wGF3jfb7lUHzvDxmM/ktGCLwwwDQYJKoZIhvcNAQEL
-BQAwXDELMAkGA1UEBhMCVVMxGTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAO
-BgNVBAcTB1NlYXR0bGUxIDAeBgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExD
-MB4XDTI0MDUwNzE3MzAzMloXDTI5MDUwNjE3MzAzMlowXDELMAkGA1UEBhMCVVMx
-GTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAOBgNVBAcTB1NlYXR0bGUxIDAe
-BgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExDMIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQCpohwYUVPH9I7Vbkb3WMe/JB0Y/bmfVj3VpcK445YBRO9K80al
-esjgBc2tAX4KYg4Lht4EBKccLHTzaNi51YEGX1aLNrSmxhz1+WtzNLNUsyY3zD9z
-vwX/3k1+JB2dRA+m+Cpwx4mjzZyAeQtHtegVaAytkmqtxQrSCexBxvqRqQIDAQAB
-o4HfMIHcMAsGA1UdDwQEAwIHgDAdBgNVHQ4EFgQU1ZXneBYnPvYXkHVlVjg7918V
-gE8wgZkGA1UdIwSBkTCBjoAU1ZXneBYnPvYXkHVlVjg7918VgE+hYKReMFwxCzAJ
-BgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdT
-ZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQ4IUe5wGF3jf
-b7lUHzvDxmM/ktGCLwwwEgYDVR0TAQH/BAgwBgEB/wIBADANBgkqhkiG9w0BAQsF
-AAOBgQCbTdpx1Iob9SwUReY4exMnlwQlmkTLyA8tYGWzchCJOJJEPfsW0ryy1A0H
-YIuvyUty3rJdp9ib8h3GZR71BkZnNddHhy06kPs4p8ewF8+d8OWtOJQcI+ZnFfG4
-KyM4rUsBrljpG2aOCm12iACEyrvgJJrS8VZwUDZS6mZEnn/lhA==
+MIIDCzCCAnSgAwIBAgIJAIe9Hnq82O7UMA0GCSqGSIb3DQEBCwUAMFwxCzAJBgNV
+BAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdTZWF0
+dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQzAeFw0yMTA3MTQx
+NDI3NTdaFw0yNDA3MTMxNDI3NTdaMFwxCzAJBgNVBAYTAlVTMRkwFwYDVQQIExBX
+YXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdTZWF0dGxlMSAwHgYDVQQKExdBbWF6
+b24gV2ViIFNlcnZpY2VzIExMQzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
+qaIcGFFTx/SO1W5G91jHvyQdGP25n1Y91aXCuOOWAUTvSvNGpXrI4AXNrQF+CmIO
+C4beBASnHCx082jYudWBBl9Wiza0psYc9flrczSzVLMmN8w/c78F/95NfiQdnUQP
+pvgqcMeJo82cgHkLR7XoFWgMrZJqrcUK0gnsQcb6kakCAwEAAaOB1DCB0TALBgNV
+HQ8EBAMCB4AwHQYDVR0OBBYEFNWV53gWJz72F5B1ZVY4O/dfFYBPMIGOBgNVHSME
+gYYwgYOAFNWV53gWJz72F5B1ZVY4O/dfFYBPoWCkXjBcMQswCQYDVQQGEwJVUzEZ
+MBcGA1UECBMQV2FzaGluZ3RvbiBTdGF0ZTEQMA4GA1UEBxMHU2VhdHRsZTEgMB4G
+A1UEChMXQW1hem9uIFdlYiBTZXJ2aWNlcyBMTEOCCQCHvR56vNju1DASBgNVHRMB
+Af8ECDAGAQH/AgEAMA0GCSqGSIb3DQEBCwUAA4GBACrKjWj460GUPZCGm3/z0dIz
+M2BPuH769wcOsqfFZcMKEysSFK91tVtUb1soFwH4/Lb/T0PqNrvtEwD1Nva5k0h2
+xZhNNRmDuhOhW1K9wCcnHGRBwY5t4lYL6hNV6hcrqYwGMjTjcAjBG2yMgznSNFle
+Rwi/S3BFXISixNx9cILu
-----END CERTIFICATE-----
# certificate for ca-west-1
@@ -451,188 +261,4 @@ RZWaBDBJy9x8C2hW+w9lMQjFHkJ7Jy/PHCJ69EzebQIDAQABMA0GCSqGSIb3DQEB
BQUAA4GBAGe9Snkz1A6rHBH6/5kDtYvtPYwhx2sXNxztbhkXErFk40Nw5l459NZx
EeudxJBLoCkkSgYjhRcOZ/gvDVtWG7qyb6fAqgoisyAbk8K9LzxSim2S1nmT9vD8
4B/t/VvwQBylc+ej8kRxMH7fquZLp7IXfmtBzyUqu6Dpbne+chG2
------END CERTIFICATE-----
-
-# certificate for ap-northeast-1
------BEGIN CERTIFICATE-----
-MIIDITCCAoqgAwIBAgIULgwDh7TiDrPPBJwscqDwiBHkEFQwDQYJKoZIhvcNAQEL
-BQAwXDELMAkGA1UEBhMCVVMxGTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAO
-BgNVBAcTB1NlYXR0bGUxIDAeBgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExD
-MB4XDTI0MDQyOTEyMjMxMFoXDTI5MDQyODEyMjMxMFowXDELMAkGA1UEBhMCVVMx
-GTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAOBgNVBAcTB1NlYXR0bGUxIDAe
-BgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExDMIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQCHvRjf/0kStpJ248khtIaN8qkDN3tkw4VjvA9nvPl2anJO+eIB
-UqPfQG09kZlwpWpmyO8bGB2RWqWxCwuB/dcnIob6w420k9WY5C0IIGtDRNauN3ku
-vGXkw3HEnF0EjYr0pcyWUvByWY4KswZV42X7Y7XSS13hOIcL6NLA+H94/QIDAQAB
-o4HfMIHcMAsGA1UdDwQEAwIHgDAdBgNVHQ4EFgQUJdbMCBXKtvCcWdwUUizvtUF2
-UTgwgZkGA1UdIwSBkTCBjoAUJdbMCBXKtvCcWdwUUizvtUF2UTihYKReMFwxCzAJ
-BgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdT
-ZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQ4IULgwDh7Ti
-DrPPBJwscqDwiBHkEFQwEgYDVR0TAQH/BAgwBgEB/wIBADANBgkqhkiG9w0BAQsF
-AAOBgQBtjAglBde1t4F9EHCZOj4qnY6Gigy07Ou54i+lR77MhbpzE8V28Li9l+YT
-QMIn6SzJqU3/fIycIro1OVY1lHmaKYgPGSEZxBenSBHfzwDLRmC9oRp4QMe0BjOC
-gepj1lUoiN7OA6PtA+ycNlsP0oJvdBjhvayLiuM3tUfLTrgHbw==
------END CERTIFICATE-----
-
-# certificate for ap-northeast-2
------BEGIN CERTIFICATE-----
-MIIDITCCAoqgAwIBAgIUbBSn2UIO6vYk4iNWV0RPxJJtHlgwDQYJKoZIhvcNAQEL
-BQAwXDELMAkGA1UEBhMCVVMxGTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAO
-BgNVBAcTB1NlYXR0bGUxIDAeBgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExD
-MB4XDTI0MDQyOTEzMzg0NloXDTI5MDQyODEzMzg0NlowXDELMAkGA1UEBhMCVVMx
-GTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAOBgNVBAcTB1NlYXR0bGUxIDAe
-BgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExDMIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQCHvRjf/0kStpJ248khtIaN8qkDN3tkw4VjvA9nvPl2anJO+eIB
-UqPfQG09kZlwpWpmyO8bGB2RWqWxCwuB/dcnIob6w420k9WY5C0IIGtDRNauN3ku
-vGXkw3HEnF0EjYr0pcyWUvByWY4KswZV42X7Y7XSS13hOIcL6NLA+H94/QIDAQAB
-o4HfMIHcMAsGA1UdDwQEAwIHgDAdBgNVHQ4EFgQUJdbMCBXKtvCcWdwUUizvtUF2
-UTgwgZkGA1UdIwSBkTCBjoAUJdbMCBXKtvCcWdwUUizvtUF2UTihYKReMFwxCzAJ
-BgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdT
-ZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQ4IUbBSn2UIO
-6vYk4iNWV0RPxJJtHlgwEgYDVR0TAQH/BAgwBgEB/wIBADANBgkqhkiG9w0BAQsF
-AAOBgQAmjTjalG8MGLqWTC2uYqEM8nzI3px1eo0ArvFRsyqQ3fgmWcQpxExqUqRy
-l3+2134Kv8dFab04Gut5wlfRtc2OwPKKicmv/IXGN+9bKFnQFjTqif08NIzrDZch
-aFT/uvxrIiM+oN2YsHq66GUhO2+xVRXDXVxM/VObFgPERbJpyA==
------END CERTIFICATE-----
-
-# certificate for ap-northeast-3
------BEGIN CERTIFICATE-----
-MIICMzCCAZygAwIBAgIGAYPou9weMA0GCSqGSIb3DQEBBQUAMFwxCzAJBgNVBAYT
-AlVTMRkwFwYDVQQIDBBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHDAdTZWF0dGxl
-MSAwHgYDVQQKDBdBbWF6b24gV2ViIFNlcnZpY2VzIExMQzAgFw0yMjEwMTgwMTM2
-MDlaGA8yMjAxMTAxODAxMzYwOVowXDELMAkGA1UEBhMCVVMxGTAXBgNVBAgMEFdh
-c2hpbmd0b24gU3RhdGUxEDAOBgNVBAcMB1NlYXR0bGUxIDAeBgNVBAoMF0FtYXpv
-biBXZWIgU2VydmljZXMgTExDMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDK
-1kIcG5Q6adBXQM75GldfTSiXl7tn54p10TnspI0ErDdb2B6q2Ji/v4XBVH13ZCMg
-qlRHMqV8AWI5iO6gFn2A9sN3AZXTMqwtZeiDdebq3k6Wt7ieYvpXTg0qvgsjQIov
-RZWaBDBJy9x8C2hW+w9lMQjFHkJ7Jy/PHCJ69EzebQIDAQABMA0GCSqGSIb3DQEB
-BQUAA4GBAGe9Snkz1A6rHBH6/5kDtYvtPYwhx2sXNxztbhkXErFk40Nw5l459NZx
-EeudxJBLoCkkSgYjhRcOZ/gvDVtWG7qyb6fAqgoisyAbk8K9LzxSim2S1nmT9vD8
-4B/t/VvwQBylc+ej8kRxMH7fquZLp7IXfmtBzyUqu6Dpbne+chG2
------END CERTIFICATE-----
-
-# certificate for ca-central-1
------BEGIN CERTIFICATE-----
-MIIDITCCAoqgAwIBAgIUIrLgixJJB5C4G8z6pZ5rB0JU2aQwDQYJKoZIhvcNAQEL
-BQAwXDELMAkGA1UEBhMCVVMxGTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAO
-BgNVBAcTB1NlYXR0bGUxIDAeBgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExD
-MB4XDTI0MDQyOTE1MzU0M1oXDTI5MDQyODE1MzU0M1owXDELMAkGA1UEBhMCVVMx
-GTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAOBgNVBAcTB1NlYXR0bGUxIDAe
-BgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExDMIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQCHvRjf/0kStpJ248khtIaN8qkDN3tkw4VjvA9nvPl2anJO+eIB
-UqPfQG09kZlwpWpmyO8bGB2RWqWxCwuB/dcnIob6w420k9WY5C0IIGtDRNauN3ku
-vGXkw3HEnF0EjYr0pcyWUvByWY4KswZV42X7Y7XSS13hOIcL6NLA+H94/QIDAQAB
-o4HfMIHcMAsGA1UdDwQEAwIHgDAdBgNVHQ4EFgQUJdbMCBXKtvCcWdwUUizvtUF2
-UTgwgZkGA1UdIwSBkTCBjoAUJdbMCBXKtvCcWdwUUizvtUF2UTihYKReMFwxCzAJ
-BgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdT
-ZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQ4IUIrLgixJJ
-B5C4G8z6pZ5rB0JU2aQwEgYDVR0TAQH/BAgwBgEB/wIBADANBgkqhkiG9w0BAQsF
-AAOBgQBHiQJmzyFAaSYs8SpiRijIDZW2RIo7qBKb/pI3rqK6yOWDlPuMr6yNI81D
-IrKGGftg4Z+2KETYU4x76HSf0s//vfH3QA57qFaAwddhKYy4BhteFQl/Wex3xTlX
-LiwI07kwJvJy3mS6UfQ4HcvZy219tY+0iyOWrz/jVxwq7TOkCw==
------END CERTIFICATE-----
-
-# certificate for eu-west-1
------BEGIN CERTIFICATE-----
-MIIDITCCAoqgAwIBAgIUakDaQ1Zqy87Hy9ESXA1pFC116HkwDQYJKoZIhvcNAQEL
-BQAwXDELMAkGA1UEBhMCVVMxGTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAO
-BgNVBAcTB1NlYXR0bGUxIDAeBgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExD
-MB4XDTI0MDQyOTE2MTgxMFoXDTI5MDQyODE2MTgxMFowXDELMAkGA1UEBhMCVVMx
-GTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAOBgNVBAcTB1NlYXR0bGUxIDAe
-BgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExDMIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQCHvRjf/0kStpJ248khtIaN8qkDN3tkw4VjvA9nvPl2anJO+eIB
-UqPfQG09kZlwpWpmyO8bGB2RWqWxCwuB/dcnIob6w420k9WY5C0IIGtDRNauN3ku
-vGXkw3HEnF0EjYr0pcyWUvByWY4KswZV42X7Y7XSS13hOIcL6NLA+H94/QIDAQAB
-o4HfMIHcMAsGA1UdDwQEAwIHgDAdBgNVHQ4EFgQUJdbMCBXKtvCcWdwUUizvtUF2
-UTgwgZkGA1UdIwSBkTCBjoAUJdbMCBXKtvCcWdwUUizvtUF2UTihYKReMFwxCzAJ
-BgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdT
-ZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQ4IUakDaQ1Zq
-y87Hy9ESXA1pFC116HkwEgYDVR0TAQH/BAgwBgEB/wIBADANBgkqhkiG9w0BAQsF
-AAOBgQADIkn/MqaLGPuK5+prZZ5Ox4bBZLPtreO2C7r0pqU2kPM2lVPyYYydkvP0
-lgSmmsErGu/oL9JNztDe2oCA+kNy17ehcsf8cw0uP861czNFKCeU8b7FgBbL+sIm
-qi33rAq6owWGi/5uEcfCR+JP7W+oSYVir5r/yDmWzx+BVH5S/g==
------END CERTIFICATE-----
-
-# certificate for eu-west-2
------BEGIN CERTIFICATE-----
-MIIDITCCAoqgAwIBAgIUCgCV/DPxYNND/swDgEKGiC5I+EwwDQYJKoZIhvcNAQEL
-BQAwXDELMAkGA1UEBhMCVVMxGTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAO
-BgNVBAcTB1NlYXR0bGUxIDAeBgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExD
-MB4XDTI0MDQyOTE2MjkxNFoXDTI5MDQyODE2MjkxNFowXDELMAkGA1UEBhMCVVMx
-GTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAOBgNVBAcTB1NlYXR0bGUxIDAe
-BgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExDMIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQCHvRjf/0kStpJ248khtIaN8qkDN3tkw4VjvA9nvPl2anJO+eIB
-UqPfQG09kZlwpWpmyO8bGB2RWqWxCwuB/dcnIob6w420k9WY5C0IIGtDRNauN3ku
-vGXkw3HEnF0EjYr0pcyWUvByWY4KswZV42X7Y7XSS13hOIcL6NLA+H94/QIDAQAB
-o4HfMIHcMAsGA1UdDwQEAwIHgDAdBgNVHQ4EFgQUJdbMCBXKtvCcWdwUUizvtUF2
-UTgwgZkGA1UdIwSBkTCBjoAUJdbMCBXKtvCcWdwUUizvtUF2UTihYKReMFwxCzAJ
-BgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdT
-ZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQ4IUCgCV/DPx
-YNND/swDgEKGiC5I+EwwEgYDVR0TAQH/BAgwBgEB/wIBADANBgkqhkiG9w0BAQsF
-AAOBgQATPu/sOE2esNa4+XPEGKlEJSgqzyBSQLQc+VWo6FAJhGG9fp7D97jhHeLC
-5vwfmtTAfnGBxadfAOT3ASkxnOZhXtnRna460LtnNHm7ArCVgXKJo7uBn6ViXtFh
-uEEw4y6p9YaLQna+VC8Xtgw6WKq2JXuKzuhuNKSFaGGw9vRcHg==
------END CERTIFICATE-----
-
-# certificate for eu-west-3
------BEGIN CERTIFICATE-----
-MIIDITCCAoqgAwIBAgIUaC9fX57UDr6u1vBvsCsECKBZQyIwDQYJKoZIhvcNAQEL
-BQAwXDELMAkGA1UEBhMCVVMxGTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAO
-BgNVBAcTB1NlYXR0bGUxIDAeBgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExD
-MB4XDTI0MDQyOTE2MzczOFoXDTI5MDQyODE2MzczOFowXDELMAkGA1UEBhMCVVMx
-GTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAOBgNVBAcTB1NlYXR0bGUxIDAe
-BgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExDMIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQCHvRjf/0kStpJ248khtIaN8qkDN3tkw4VjvA9nvPl2anJO+eIB
-UqPfQG09kZlwpWpmyO8bGB2RWqWxCwuB/dcnIob6w420k9WY5C0IIGtDRNauN3ku
-vGXkw3HEnF0EjYr0pcyWUvByWY4KswZV42X7Y7XSS13hOIcL6NLA+H94/QIDAQAB
-o4HfMIHcMAsGA1UdDwQEAwIHgDAdBgNVHQ4EFgQUJdbMCBXKtvCcWdwUUizvtUF2
-UTgwgZkGA1UdIwSBkTCBjoAUJdbMCBXKtvCcWdwUUizvtUF2UTihYKReMFwxCzAJ
-BgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdT
-ZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQ4IUaC9fX57U
-Dr6u1vBvsCsECKBZQyIwEgYDVR0TAQH/BAgwBgEB/wIBADANBgkqhkiG9w0BAQsF
-AAOBgQCARv1bQEDaMEzYI0nPlu8GHcMXgmgA94HyrXhMMcaIlQwocGBs6VILGVhM
-TXP2r3JFaPEpmXSQNQHvGA13clKwAZbni8wtzv6qXb4L4muF34iQRHF0nYrEDoK7
-mMPR8+oXKKuPO/mv/XKo6XAV5DDERdSYHX5kkA2R9wtvyZjPnQ==
------END CERTIFICATE-----
-
-# certificate for eu-north-1
------BEGIN CERTIFICATE-----
-MIIDITCCAoqgAwIBAgIUN1c9U6U/xiVDFgJcYKZB4NkH1QEwDQYJKoZIhvcNAQEL
-BQAwXDELMAkGA1UEBhMCVVMxGTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAO
-BgNVBAcTB1NlYXR0bGUxIDAeBgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExD
-MB4XDTI0MDQyOTE2MDYwM1oXDTI5MDQyODE2MDYwM1owXDELMAkGA1UEBhMCVVMx
-GTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAOBgNVBAcTB1NlYXR0bGUxIDAe
-BgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExDMIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQCHvRjf/0kStpJ248khtIaN8qkDN3tkw4VjvA9nvPl2anJO+eIB
-UqPfQG09kZlwpWpmyO8bGB2RWqWxCwuB/dcnIob6w420k9WY5C0IIGtDRNauN3ku
-vGXkw3HEnF0EjYr0pcyWUvByWY4KswZV42X7Y7XSS13hOIcL6NLA+H94/QIDAQAB
-o4HfMIHcMAsGA1UdDwQEAwIHgDAdBgNVHQ4EFgQUJdbMCBXKtvCcWdwUUizvtUF2
-UTgwgZkGA1UdIwSBkTCBjoAUJdbMCBXKtvCcWdwUUizvtUF2UTihYKReMFwxCzAJ
-BgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdT
-ZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQ4IUN1c9U6U/
-xiVDFgJcYKZB4NkH1QEwEgYDVR0TAQH/BAgwBgEB/wIBADANBgkqhkiG9w0BAQsF
-AAOBgQBTIQdoFSDRHkpqNPUbZ9WXR2O5v/9bpmHojMYZb3Hw46wsaRso7STiGGX/
-tRqjIkPUIXsdhZ3+7S/RmhFznmZc8e0bjU4n5vi9CJtQSt+1u4E17+V2bF+D3h/7
-wcfE0l3414Q8JaTDtfEf/aF3F0uyBvr4MDMd7mFvAMmDmBPSlA==
------END CERTIFICATE-----
-
-# certificate for sa-east-1
------BEGIN CERTIFICATE-----
-MIIDITCCAoqgAwIBAgIUX4Bh4MQ86Roh37VDRRX1MNOB3TcwDQYJKoZIhvcNAQEL
-BQAwXDELMAkGA1UEBhMCVVMxGTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAO
-BgNVBAcTB1NlYXR0bGUxIDAeBgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExD
-MB4XDTI0MDQyOTE2NDYwOVoXDTI5MDQyODE2NDYwOVowXDELMAkGA1UEBhMCVVMx
-GTAXBgNVBAgTEFdhc2hpbmd0b24gU3RhdGUxEDAOBgNVBAcTB1NlYXR0bGUxIDAe
-BgNVBAoTF0FtYXpvbiBXZWIgU2VydmljZXMgTExDMIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQCHvRjf/0kStpJ248khtIaN8qkDN3tkw4VjvA9nvPl2anJO+eIB
-UqPfQG09kZlwpWpmyO8bGB2RWqWxCwuB/dcnIob6w420k9WY5C0IIGtDRNauN3ku
-vGXkw3HEnF0EjYr0pcyWUvByWY4KswZV42X7Y7XSS13hOIcL6NLA+H94/QIDAQAB
-o4HfMIHcMAsGA1UdDwQEAwIHgDAdBgNVHQ4EFgQUJdbMCBXKtvCcWdwUUizvtUF2
-UTgwgZkGA1UdIwSBkTCBjoAUJdbMCBXKtvCcWdwUUizvtUF2UTihYKReMFwxCzAJ
-BgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdT
-ZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQ4IUX4Bh4MQ8
-6Roh37VDRRX1MNOB3TcwEgYDVR0TAQH/BAgwBgEB/wIBADANBgkqhkiG9w0BAQsF
-AAOBgQBnhocfH6ZIX6F5K9+Y9V4HFk8vSaaKL5ytw/P5td1h9ej94KF3xkZ5fyjN
-URvGQv3kNmNJBoNarcP9I7JIMjsNPmVzqWawyCEGCZImoARxSS3Fc5EAs2PyBfcD
-9nCtzMTaKO09Xyq0wqXVYn1xJsE5d5yBDsGrzaTHKjxo61+ezQ==
------END CERTIFICATE-----
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/vendor/github.com/smallstep/certificates/authority/provisioner/azure.go b/vendor/github.com/smallstep/certificates/authority/provisioner/azure.go
index 0a86b64..a9d5d1f 100644
--- a/vendor/github.com/smallstep/certificates/authority/provisioner/azure.go
+++ b/vendor/github.com/smallstep/certificates/authority/provisioner/azure.go
@@ -251,14 +251,14 @@ func (p *Azure) Init(config Config) (err error) {
p.assertConfig()
// Decode and validate openid-configuration endpoint
- if err = getAndDecode(http.DefaultClient, p.config.oidcDiscoveryURL, &p.oidcConfig); err != nil {
+ if err = getAndDecode(p.config.oidcDiscoveryURL, &p.oidcConfig); err != nil {
return
}
if err := p.oidcConfig.Validate(); err != nil {
return errors.Wrapf(err, "error parsing %s", p.config.oidcDiscoveryURL)
}
// Get JWK key set
- if p.keyStore, err = newKeyStore(http.DefaultClient, p.oidcConfig.JWKSetURI); err != nil {
+ if p.keyStore, err = newKeyStore(p.oidcConfig.JWKSetURI); err != nil {
return
}
@@ -379,7 +379,7 @@ func (p *Azure) AuthorizeSign(ctx context.Context, token string) ([]SignOption,
// name will work only inside the virtual network
so = append(so,
commonNameValidator(name),
- dnsNamesSubsetValidator([]string{name}),
+ dnsNamesValidator([]string{name}),
ipAddressesValidator(nil),
emailAddressesValidator(nil),
newURIsValidator(ctx, nil),
diff --git a/vendor/github.com/smallstep/certificates/authority/provisioner/claims.go b/vendor/github.com/smallstep/certificates/authority/provisioner/claims.go
index 993bf49..dcf679b 100644
--- a/vendor/github.com/smallstep/certificates/authority/provisioner/claims.go
+++ b/vendor/github.com/smallstep/certificates/authority/provisioner/claims.go
@@ -234,24 +234,24 @@ func (c *Claimer) IsSSHCAEnabled() bool {
// Validate validates and modifies the Claims with default values.
func (c *Claimer) Validate() error {
var (
- minDur = c.MinTLSCertDuration()
- maxDur = c.MaxTLSCertDuration()
- defDur = c.DefaultTLSCertDuration()
+ min = c.MinTLSCertDuration()
+ max = c.MaxTLSCertDuration()
+ def = c.DefaultTLSCertDuration()
)
switch {
- case minDur <= 0:
+ case min <= 0:
return errors.Errorf("claims: MinTLSCertDuration must be greater than 0")
- case maxDur <= 0:
+ case max <= 0:
return errors.Errorf("claims: MaxTLSCertDuration must be greater than 0")
- case defDur <= 0:
+ case def <= 0:
return errors.Errorf("claims: DefaultTLSCertDuration must be greater than 0")
- case maxDur < minDur:
+ case max < min:
return errors.Errorf("claims: MaxCertDuration cannot be less "+
- "than MinCertDuration: MaxCertDuration - %v, MinCertDuration - %v", maxDur, minDur)
- case defDur < minDur:
- return errors.Errorf("claims: DefaultCertDuration cannot be less than MinCertDuration: DefaultCertDuration - %v, MinCertDuration - %v", defDur, minDur)
- case maxDur < defDur:
- return errors.Errorf("claims: MaxCertDuration cannot be less than DefaultCertDuration: MaxCertDuration - %v, DefaultCertDuration - %v", maxDur, defDur)
+ "than MinCertDuration: MaxCertDuration - %v, MinCertDuration - %v", max, min)
+ case def < min:
+ return errors.Errorf("claims: DefaultCertDuration cannot be less than MinCertDuration: DefaultCertDuration - %v, MinCertDuration - %v", def, min)
+ case max < def:
+ return errors.Errorf("claims: MaxCertDuration cannot be less than DefaultCertDuration: MaxCertDuration - %v, DefaultCertDuration - %v", max, def)
default:
return nil
}
diff --git a/vendor/github.com/smallstep/certificates/authority/provisioner/controller.go b/vendor/github.com/smallstep/certificates/authority/provisioner/controller.go
index 8d95aaf..09f6a6b 100644
--- a/vendor/github.com/smallstep/certificates/authority/provisioner/controller.go
+++ b/vendor/github.com/smallstep/certificates/authority/provisioner/controller.go
@@ -26,7 +26,6 @@ type Controller struct {
policy *policyEngine
webhookClient *http.Client
webhooks []*Webhook
- httpClient *http.Client
}
// NewController initializes a new provisioner controller.
@@ -49,19 +48,9 @@ func NewController(p Interface, claims *Claims, config Config, options *Options)
policy: policy,
webhookClient: config.WebhookClient,
webhooks: options.GetWebhooks(),
- httpClient: config.HTTPClient,
}, nil
}
-// GetHTTPClient returns the configured HTTP client or the default one if none
-// is configured.
-func (c *Controller) GetHTTPClient() *http.Client {
- if c.httpClient != nil {
- return c.httpClient
- }
- return &http.Client{}
-}
-
// GetIdentity returns the identity for a given email.
func (c *Controller) GetIdentity(ctx context.Context, email string) (*Identity, error) {
if c.IdentityFunc != nil {
diff --git a/vendor/github.com/smallstep/certificates/authority/provisioner/gcp.go b/vendor/github.com/smallstep/certificates/authority/provisioner/gcp.go
index c63a29c..2296b1b 100644
--- a/vendor/github.com/smallstep/certificates/authority/provisioner/gcp.go
+++ b/vendor/github.com/smallstep/certificates/authority/provisioner/gcp.go
@@ -30,12 +30,6 @@ const gcpCertsURL = "https://www.googleapis.com/oauth2/v3/certs"
// gcpIdentityURL is the base url for the identity document in GCP.
const gcpIdentityURL = "http://metadata/computeMetadata/v1/instance/service-accounts/default/identity"
-// DefaultDisableSSHCAHost is the default value for SSH Host CA used when DisableSSHCAHost is not set
-var DefaultDisableSSHCAHost = false
-
-// DefaultDisableSSHCAUser is the default value for SSH User CA used when DisableSSHCAUser is not set
-var DefaultDisableSSHCAUser = true
-
// gcpPayload extends jwt.Claims with custom GCP attributes.
type gcpPayload struct {
jose.Claims
@@ -95,8 +89,6 @@ type GCP struct {
ProjectIDs []string `json:"projectIDs"`
DisableCustomSANs bool `json:"disableCustomSANs"`
DisableTrustOnFirstUse bool `json:"disableTrustOnFirstUse"`
- DisableSSHCAUser *bool `json:"disableSSHCAUser,omitempty"`
- DisableSSHCAHost *bool `json:"disableSSHCAHost,omitempty"`
InstanceAge Duration `json:"instanceAge,omitempty"`
Claims *Claims `json:"claims,omitempty"`
Options *Options `json:"options,omitempty"`
@@ -207,14 +199,6 @@ func (p *GCP) GetIdentityToken(subject, caURL string) (string, error) {
// Init validates and initializes the GCP provisioner.
func (p *GCP) Init(config Config) (err error) {
- if p.DisableSSHCAHost == nil {
- p.DisableSSHCAHost = &DefaultDisableSSHCAHost
- }
-
- if p.DisableSSHCAUser == nil {
- p.DisableSSHCAUser = &DefaultDisableSSHCAUser
- }
-
switch {
case p.Type == "":
return errors.New("provisioner type cannot be empty")
@@ -228,7 +212,7 @@ func (p *GCP) Init(config Config) (err error) {
p.assertConfig()
// Initialize key store
- if p.keyStore, err = newKeyStore(http.DefaultClient, p.config.CertsURL); err != nil {
+ if p.keyStore, err = newKeyStore(p.config.CertsURL); err != nil {
return
}
@@ -265,7 +249,7 @@ func (p *GCP) AuthorizeSign(ctx context.Context, token string) ([]SignOption, er
commonNameSliceValidator([]string{
ce.InstanceName, ce.InstanceID, dnsName1, dnsName2,
}),
- dnsNamesSubsetValidator([]string{
+ dnsNamesValidator([]string{
dnsName1, dnsName2,
}),
ipAddressesValidator(nil),
@@ -403,41 +387,31 @@ func (p *GCP) authorizeToken(token string) (*gcpPayload, error) {
}
// AuthorizeSSHSign returns the list of SignOption for a SignSSH request.
-func (p *GCP) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption, error) {
- certType, hasCertType := CertTypeFromContext(ctx)
- if !hasCertType {
- certType = SSHHostCert
- }
-
- err := p.isUnauthorizedToIssueSSHCert(certType)
- if err != nil {
- return nil, err
+func (p *GCP) AuthorizeSSHSign(_ context.Context, token string) ([]SignOption, error) {
+ if !p.ctl.Claimer.IsSSHCAEnabled() {
+ return nil, errs.Unauthorized("gcp.AuthorizeSSHSign; sshCA is disabled for gcp provisioner '%s'", p.GetName())
}
-
claims, err := p.authorizeToken(token)
if err != nil {
return nil, errs.Wrap(http.StatusInternalServerError, err, "gcp.AuthorizeSSHSign")
}
- var principals []string
- var keyID string
- var defaults SignSSHOptions
- var ct sshutil.CertType
- var template string
+ ce := claims.Google.ComputeEngine
+ signOptions := []SignOption{}
- switch certType {
- case SSHHostCert:
- defaults, keyID, principals, ct, template = p.genHostOptions(ctx, claims)
- case SSHUserCert:
- defaults, keyID, principals, ct, template = p.genUserOptions(ctx, claims)
- default:
- return nil, errs.Unauthorized("gcp.AuthorizeSSHSign; invalid requested certType")
+ // Enforce host certificate.
+ defaults := SignSSHOptions{
+ CertType: SSHHostCert,
}
- signOptions := []SignOption{}
+ // Validated principals.
+ principals := []string{
+ fmt.Sprintf("%s.c.%s.internal", ce.InstanceName, ce.ProjectID),
+ fmt.Sprintf("%s.%s.c.%s.internal", ce.InstanceName, ce.Zone, ce.ProjectID),
+ }
- // Only enforce known principals if disable custom sans is true, or it is a user cert request
- if p.DisableCustomSANs || certType == SSHUserCert {
+ // Only enforce known principals if disable custom sans is true.
+ if p.DisableCustomSANs {
defaults.Principals = principals
} else {
// Check that at least one principal is sent in the request.
@@ -447,12 +421,12 @@ func (p *GCP) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption,
}
// Certificate templates.
- data := sshutil.CreateTemplateData(ct, keyID, principals)
+ data := sshutil.CreateTemplateData(sshutil.HostCert, ce.InstanceName, principals)
if v, err := unsafeParseSigned(token); err == nil {
data.SetToken(v)
}
- templateOptions, err := CustomSSHTemplateOptions(p.Options, data, template)
+ templateOptions, err := CustomSSHTemplateOptions(p.Options, data, sshutil.DefaultIIDTemplate)
if err != nil {
return nil, errs.Wrap(http.StatusInternalServerError, err, "gcp.AuthorizeSSHSign")
}
@@ -471,54 +445,12 @@ func (p *GCP) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption,
// Require all the fields in the SSH certificate
&sshCertDefaultValidator{},
// Ensure that all principal names are allowed
- newSSHNamePolicyValidator(p.ctl.getPolicy().getSSHHost(), p.ctl.getPolicy().getSSHUser()),
+ newSSHNamePolicyValidator(p.ctl.getPolicy().getSSHHost(), nil),
// Call webhooks
p.ctl.newWebhookController(
data,
linkedca.Webhook_SSH,
- webhook.WithAuthorizationPrincipal(keyID),
+ webhook.WithAuthorizationPrincipal(ce.InstanceID),
),
), nil
}
-
-func (p *GCP) genHostOptions(_ context.Context, claims *gcpPayload) (SignSSHOptions, string, []string, sshutil.CertType, string) {
- ce := claims.Google.ComputeEngine
- keyID := ce.InstanceName
-
- principals := []string{
- fmt.Sprintf("%s.c.%s.internal", ce.InstanceName, ce.ProjectID),
- fmt.Sprintf("%s.%s.c.%s.internal", ce.InstanceName, ce.Zone, ce.ProjectID),
- }
-
- return SignSSHOptions{CertType: SSHHostCert}, keyID, principals, sshutil.HostCert, sshutil.DefaultIIDTemplate
-}
-
-func FormatServiceAccountUsername(serviceAccountID string) string {
- return fmt.Sprintf("sa_%v", serviceAccountID)
-}
-
-func (p *GCP) genUserOptions(_ context.Context, claims *gcpPayload) (SignSSHOptions, string, []string, sshutil.CertType, string) {
- keyID := claims.Email
- principals := []string{
- FormatServiceAccountUsername(claims.Subject),
- claims.Email,
- }
-
- return SignSSHOptions{CertType: SSHUserCert}, keyID, principals, sshutil.UserCert, sshutil.DefaultTemplate
-}
-
-func (p *GCP) isUnauthorizedToIssueSSHCert(certType string) error {
- if !p.ctl.Claimer.IsSSHCAEnabled() {
- return errs.Unauthorized("gcp.AuthorizeSSHSign; sshCA is disabled for gcp provisioner '%s'", p.GetName())
- }
-
- if certType == SSHHostCert && *p.DisableSSHCAHost {
- return errs.Unauthorized("gcp.AuthorizeSSHSign; sshCA for Hosts is disabled for gcp provisioner '%s'", p.GetName())
- }
-
- if certType == SSHUserCert && *p.DisableSSHCAUser {
- return errs.Unauthorized("gcp.AuthorizeSSHSign; sshCA for Users is disabled for gcp provisioner '%s'", p.GetName())
- }
-
- return nil
-}
diff --git a/vendor/github.com/smallstep/certificates/authority/provisioner/jwk.go b/vendor/github.com/smallstep/certificates/authority/provisioner/jwk.go
index 70a6706..13e8bd4 100644
--- a/vendor/github.com/smallstep/certificates/authority/provisioner/jwk.go
+++ b/vendor/github.com/smallstep/certificates/authority/provisioner/jwk.go
@@ -19,9 +19,8 @@ import (
// jwtPayload extends jwt.Claims with step attributes.
type jwtPayload struct {
jose.Claims
- SANs []string `json:"sans,omitempty"`
- Step *stepPayload `json:"step,omitempty"`
- Confirmation *cnfPayload `json:"cnf,omitempty"`
+ SANs []string `json:"sans,omitempty"`
+ Step *stepPayload `json:"step,omitempty"`
}
type stepPayload struct {
@@ -29,10 +28,6 @@ type stepPayload struct {
RA *RAInfo `json:"ra,omitempty"`
}
-type cnfPayload struct {
- Fingerprint string `json:"x5rt#S256,omitempty"`
-}
-
// JWK is the default provisioner, an entity that can sign tokens necessary for
// signature requests.
type JWK struct {
@@ -188,12 +183,6 @@ func (p *JWK) AuthorizeSign(ctx context.Context, token string) ([]SignOption, er
}
}
- // Check the fingerprint of the certificate request if given.
- var fingerprint string
- if claims.Confirmation != nil {
- fingerprint = claims.Confirmation.Fingerprint
- }
-
return []SignOption{
self,
templateOptions,
@@ -201,7 +190,6 @@ func (p *JWK) AuthorizeSign(ctx context.Context, token string) ([]SignOption, er
newProvisionerExtensionOption(TypeJWK, p.Name, p.Key.KeyID).WithControllerOptions(p.ctl),
profileDefaultDuration(p.ctl.Claimer.DefaultTLSCertDuration()),
// validators
- csrFingerprintValidator(fingerprint),
commonNameSliceValidator(append([]string{claims.Subject}, claims.SANs...)),
defaultPublicKeyValidator{},
newDefaultSANsValidator(ctx, claims.SANs),
@@ -249,7 +237,7 @@ func (p *JWK) AuthorizeSSHSign(_ context.Context, token string) ([]SignOption, e
// Use options in the token.
if opts.CertType != "" {
if certType, err = sshutil.CertTypeFromString(opts.CertType); err != nil {
- return nil, errs.BadRequestErr(err, err.Error()) //nolint:govet // allow non-constant error messages
+ return nil, errs.BadRequestErr(err, err.Error())
}
}
if opts.KeyID != "" {
diff --git a/vendor/github.com/smallstep/certificates/authority/provisioner/keystore.go b/vendor/github.com/smallstep/certificates/authority/provisioner/keystore.go
index 23a4e9a..aeaad6a 100644
--- a/vendor/github.com/smallstep/certificates/authority/provisioner/keystore.go
+++ b/vendor/github.com/smallstep/certificates/authority/provisioner/keystore.go
@@ -22,7 +22,6 @@ var maxAgeRegex = regexp.MustCompile(`max-age=(\d+)`)
type keyStore struct {
sync.RWMutex
- client *http.Client
uri string
keySet jose.JSONWebKeySet
timer *time.Timer
@@ -30,13 +29,12 @@ type keyStore struct {
jitter time.Duration
}
-func newKeyStore(client *http.Client, uri string) (*keyStore, error) {
- keys, age, err := getKeysFromJWKsURI(client, uri)
+func newKeyStore(uri string) (*keyStore, error) {
+ keys, age, err := getKeysFromJWKsURI(uri)
if err != nil {
return nil, err
}
ks := &keyStore{
- client: client,
uri: uri,
keySet: keys,
expiry: getExpirationTime(age),
@@ -66,7 +64,7 @@ func (ks *keyStore) Get(kid string) (keys []jose.JSONWebKey) {
func (ks *keyStore) reload() {
var next time.Duration
- keys, age, err := getKeysFromJWKsURI(ks.client, ks.uri)
+ keys, age, err := getKeysFromJWKsURI(ks.uri)
if err != nil {
next = ks.nextReloadDuration(ks.jitter / 2)
} else {
@@ -92,9 +90,9 @@ func (ks *keyStore) nextReloadDuration(age time.Duration) time.Duration {
return abs(age)
}
-func getKeysFromJWKsURI(client *http.Client, uri string) (jose.JSONWebKeySet, time.Duration, error) {
+func getKeysFromJWKsURI(uri string) (jose.JSONWebKeySet, time.Duration, error) {
var keys jose.JSONWebKeySet
- resp, err := client.Get(uri)
+ resp, err := http.Get(uri) //nolint:gosec // openid-configuration jwks_uri
if err != nil {
return keys, 0, errors.Wrapf(err, "failed to connect to %s", uri)
}
diff --git a/vendor/github.com/smallstep/certificates/authority/provisioner/method.go b/vendor/github.com/smallstep/certificates/authority/provisioner/method.go
index d01ce12..19aa622 100644
--- a/vendor/github.com/smallstep/certificates/authority/provisioner/method.go
+++ b/vendor/github.com/smallstep/certificates/authority/provisioner/method.go
@@ -78,17 +78,3 @@ func TokenFromContext(ctx context.Context) (string, bool) {
token, ok := ctx.Value(tokenKey{}).(string)
return token, ok
}
-
-// The key to save the certTypeKey in the context.
-type certTypeKey struct{}
-
-// NewContextWithCertType creates a new context with the given CertType.
-func NewContextWithCertType(ctx context.Context, certType string) context.Context {
- return context.WithValue(ctx, certTypeKey{}, certType)
-}
-
-// CertTypeFromContext returns the certType stored in the given context.
-func CertTypeFromContext(ctx context.Context) (string, bool) {
- certType, ok := ctx.Value(certTypeKey{}).(string)
- return certType, ok
-}
diff --git a/vendor/github.com/smallstep/certificates/authority/provisioner/nebula.go b/vendor/github.com/smallstep/certificates/authority/provisioner/nebula.go
index fa9c283..66c523d 100644
--- a/vendor/github.com/smallstep/certificates/authority/provisioner/nebula.go
+++ b/vendor/github.com/smallstep/certificates/authority/provisioner/nebula.go
@@ -2,13 +2,9 @@ package provisioner
import (
"context"
- "crypto/ecdh"
- "crypto/ecdsa"
"crypto/ed25519"
- "crypto/elliptic"
"crypto/x509"
"encoding/base64"
- "math/big"
"net"
"time"
@@ -341,23 +337,10 @@ func (p *Nebula) authorizeToken(token string, audiences []string) (*nebula.Nebul
return nil, nil, errs.Unauthorized("token is not valid: failed to verify certificate against configured CA")
}
- var pub any
- switch {
- case c.Details.Curve == nebula.Curve_P256:
- // When Nebula is used with ECDSA P-256 keys, both CAs and clients use the same type.
- ecdhPub, err := ecdh.P256().NewPublicKey(c.Details.PublicKey)
- if err != nil {
- return nil, nil, errs.UnauthorizedErr(err, errs.WithMessage("failed to parse nebula public key"))
- }
- publicKeyBytes := ecdhPub.Bytes()
- pub = &ecdsa.PublicKey{ // convert back to *ecdsa.PublicKey, because our jose package nor go-jose supports *ecdh.PublicKey
- Curve: elliptic.P256(),
- X: big.NewInt(0).SetBytes(publicKeyBytes[1:33]),
- Y: big.NewInt(0).SetBytes(publicKeyBytes[33:]),
- }
- case c.Details.IsCA:
+ var pub interface{}
+ if c.Details.IsCA {
pub = ed25519.PublicKey(c.Details.PublicKey)
- default:
+ } else {
pub = x25519.PublicKey(c.Details.PublicKey)
}
@@ -375,7 +358,6 @@ func (p *Nebula) authorizeToken(token string, audiences []string) (*nebula.Nebul
}, time.Minute); err != nil {
return nil, nil, errs.UnauthorizedErr(err, errs.WithMessage("token is not valid: invalid claims"))
}
-
// Validate token and subject too.
if !matchesAudience(claims.Audience, audiences) {
return nil, nil, errs.Unauthorized("token is not valid: invalid claims")
diff --git a/vendor/github.com/smallstep/certificates/authority/provisioner/oidc.go b/vendor/github.com/smallstep/certificates/authority/provisioner/oidc.go
index 25d29b5..06823e2 100644
--- a/vendor/github.com/smallstep/certificates/authority/provisioner/oidc.go
+++ b/vendor/github.com/smallstep/certificates/authority/provisioner/oidc.go
@@ -93,8 +93,6 @@ type OIDC struct {
ListenAddress string `json:"listenAddress,omitempty"`
Claims *Claims `json:"claims,omitempty"`
Options *Options `json:"options,omitempty"`
- Scopes []string `json:"scopes,omitempty"`
- AuthParams []string `json:"authParams,omitempty"`
configuration openIDConfiguration
keyStore *keyStore
ctl *Controller
@@ -184,29 +182,23 @@ func (o *OIDC) Init(config Config) (err error) {
if !strings.Contains(u.Path, "/.well-known/openid-configuration") {
u.Path = path.Join(u.Path, "/.well-known/openid-configuration")
}
-
- // Initialize the common provisioner controller
- o.ctl, err = NewController(o, o.Claims, config, o.Options)
- if err != nil {
- return err
- }
-
- // Decode and validate openid-configuration
- httpClient := o.ctl.GetHTTPClient()
- if err := getAndDecode(httpClient, u.String(), &o.configuration); err != nil {
+ if err := getAndDecode(u.String(), &o.configuration); err != nil {
return err
}
if err := o.configuration.Validate(); err != nil {
return errors.Wrapf(err, "error parsing %s", o.ConfigurationEndpoint)
}
-
// Replace {tenantid} with the configured one
if o.TenantID != "" {
o.configuration.Issuer = strings.ReplaceAll(o.configuration.Issuer, "{tenantid}", o.TenantID)
}
-
// Get JWK key set
- o.keyStore, err = newKeyStore(httpClient, o.configuration.JWKSetURI)
+ o.keyStore, err = newKeyStore(o.configuration.JWKSetURI)
+ if err != nil {
+ return err
+ }
+
+ o.ctl, err = NewController(o, o.Claims, config, o.Options)
return
}
@@ -485,8 +477,8 @@ func (o *OIDC) AuthorizeSSHRevoke(_ context.Context, token string) error {
return errs.Unauthorized("oidc.AuthorizeSSHRevoke; cannot revoke with non-admin oidc token")
}
-func getAndDecode(client *http.Client, uri string, v interface{}) error {
- resp, err := client.Get(uri)
+func getAndDecode(uri string, v interface{}) error {
+ resp, err := http.Get(uri) //nolint:gosec // openid-configuration uri
if err != nil {
return errors.Wrapf(err, "failed to connect to %s", uri)
}
diff --git a/vendor/github.com/smallstep/certificates/authority/provisioner/options.go b/vendor/github.com/smallstep/certificates/authority/provisioner/options.go
index f68e9da..cbce43d 100644
--- a/vendor/github.com/smallstep/certificates/authority/provisioner/options.go
+++ b/vendor/github.com/smallstep/certificates/authority/provisioner/options.go
@@ -6,12 +6,11 @@ import (
"github.com/pkg/errors"
- "github.com/smallstep/cli-utils/step"
+ "go.step.sm/cli-utils/step"
"go.step.sm/crypto/jose"
"go.step.sm/crypto/x509util"
"github.com/smallstep/certificates/authority/policy"
- "github.com/smallstep/certificates/authority/provisioner/wire"
)
// CertificateOptions is an interface that returns a list of options passed when
@@ -31,10 +30,9 @@ func (fn certificateOptionsFunc) Options(so SignOptions) []x509util.Option {
type Options struct {
X509 *X509Options `json:"x509,omitempty"`
SSH *SSHOptions `json:"ssh,omitempty"`
+
// Webhooks is a list of webhooks that can augment template data
Webhooks []*Webhook `json:"webhooks,omitempty"`
- // Wire holds the options used for the ACME Wire integration
- Wire *wire.Options `json:"wire,omitempty"`
}
// GetX509Options returns the X.509 options.
@@ -53,18 +51,6 @@ func (o *Options) GetSSHOptions() *SSHOptions {
return o.SSH
}
-// GetWireOptions returns the Wire options if available. It
-// returns an error if they're not available.
-func (o *Options) GetWireOptions() (*wire.Options, error) {
- if o == nil {
- return nil, errors.New("no options available")
- }
- if o.Wire == nil {
- return nil, errors.New("no Wire options available")
- }
- return o.Wire, nil
-}
-
// GetWebhooks returns the webhooks options.
func (o *Options) GetWebhooks() []*Webhook {
if o == nil {
diff --git a/vendor/github.com/smallstep/certificates/authority/provisioner/provisioner.go b/vendor/github.com/smallstep/certificates/authority/provisioner/provisioner.go
index 24792f6..73397a3 100644
--- a/vendor/github.com/smallstep/certificates/authority/provisioner/provisioner.go
+++ b/vendor/github.com/smallstep/certificates/authority/provisioner/provisioner.go
@@ -34,31 +34,6 @@ type Interface interface {
AuthorizeSSHRekey(ctx context.Context, token string) (*ssh.Certificate, []SignOption, error)
}
-// Uninitialized represents a disabled provisioner. Uninitialized provisioners
-// are created when the Init methods fails.
-type Uninitialized struct {
- Interface
- Reason error
-}
-
-// MarshalJSON returns the JSON encoding of the provisioner with the disabled
-// reason.
-func (p Uninitialized) MarshalJSON() ([]byte, error) {
- provisionerJSON, err := json.Marshal(p.Interface)
- if err != nil {
- return nil, err
- }
- reasonJSON, err := json.Marshal(struct {
- State string `json:"state"`
- StateReason string `json:"stateReason"`
- }{"Uninitialized", p.Reason.Error()})
- if err != nil {
- return nil, err
- }
- reasonJSON[0] = ','
- return append(provisionerJSON[:len(provisionerJSON)-1], reasonJSON...), nil
-}
-
// ErrAllowTokenReuse is an error that is returned by provisioners that allows
// the reuse of tokens.
//
@@ -246,7 +221,7 @@ type Config struct {
Claims Claims
// Audiences are the audiences used in the default provisioner, (JWK).
Audiences Audiences
- // SSHKeys are the root SSH public keys.
+ // SSHKeys are the root SSH public keys
SSHKeys *SSHKeys
// GetIdentityFunc is a function that returns an identity that will be
// used by the provisioner to populate certificate attributes.
@@ -257,13 +232,10 @@ type Config struct {
// AuthorizeSSHRenewFunc is a function that returns nil if a given SSH
// certificate can be renewed.
AuthorizeSSHRenewFunc AuthorizeSSHRenewFunc
- // WebhookClient is an HTTP client used when performing webhook requests.
+ // WebhookClient is an http client to use in webhook request
WebhookClient *http.Client
// SCEPKeyManager, if defined, is the interface used by SCEP provisioners.
SCEPKeyManager SCEPKeyManager
- // HTTPClient is an HTTP client that trusts the system cert pool and the CA
- // roots.
- HTTPClient *http.Client
}
type provisioner struct {
diff --git a/vendor/github.com/smallstep/certificates/authority/provisioner/scep.go b/vendor/github.com/smallstep/certificates/authority/provisioner/scep.go
index 0bdaf3e..7213285 100644
--- a/vendor/github.com/smallstep/certificates/authority/provisioner/scep.go
+++ b/vendor/github.com/smallstep/certificates/authority/provisioner/scep.go
@@ -15,7 +15,6 @@ import (
"go.step.sm/crypto/kms"
kmsapi "go.step.sm/crypto/kms/apiv1"
- "go.step.sm/crypto/x509util"
"go.step.sm/linkedca"
"github.com/smallstep/certificates/webhook"
@@ -146,33 +145,25 @@ var (
// that case, the other webhooks will be skipped. If none of
// the webhooks indicates the value of the challenge was accepted,
// an error is returned.
-func (c *challengeValidationController) Validate(ctx context.Context, csr *x509.CertificateRequest, provisionerName, challenge, transactionID string) ([]SignCSROption, error) {
- var opts []SignCSROption
-
+func (c *challengeValidationController) Validate(ctx context.Context, csr *x509.CertificateRequest, provisionerName, challenge, transactionID string) error {
for _, wh := range c.webhooks {
req, err := webhook.NewRequestBody(webhook.WithX509CertificateRequest(csr))
if err != nil {
- return nil, fmt.Errorf("failed creating new webhook request: %w", err)
+ return fmt.Errorf("failed creating new webhook request: %w", err)
}
req.ProvisionerName = provisionerName
req.SCEPChallenge = challenge
req.SCEPTransactionID = transactionID
resp, err := wh.DoWithContext(ctx, c.client, req, nil) // TODO(hs): support templated URL? Requires some refactoring
if err != nil {
- return nil, fmt.Errorf("failed executing webhook request: %w", err)
+ return fmt.Errorf("failed executing webhook request: %w", err)
}
if resp.Allow {
- opts = append(opts, TemplateDataModifierFunc(func(data x509util.TemplateData) {
- data.SetWebhook(wh.Name, resp.Data)
- }))
+ return nil // return early when response is positive
}
}
- if len(opts) == 0 {
- return nil, ErrSCEPChallengeInvalid
- }
-
- return opts, nil
+ return ErrSCEPChallengeInvalid
}
type notificationController struct {
@@ -449,18 +440,18 @@ func (s *SCEP) GetContentEncryptionAlgorithm() int {
// ValidateChallenge validates the provided challenge. It starts by
// selecting the validation method to use, then performs validation
// according to that method.
-func (s *SCEP) ValidateChallenge(ctx context.Context, csr *x509.CertificateRequest, challenge, transactionID string) ([]SignCSROption, error) {
+func (s *SCEP) ValidateChallenge(ctx context.Context, csr *x509.CertificateRequest, challenge, transactionID string) error {
if s.challengeValidationController == nil {
- return nil, fmt.Errorf("provisioner %q wasn't initialized", s.Name)
+ return fmt.Errorf("provisioner %q wasn't initialized", s.Name)
}
switch s.selectValidationMethod() {
case validationMethodWebhook:
return s.challengeValidationController.Validate(ctx, csr, s.Name, challenge, transactionID)
default:
if subtle.ConstantTimeCompare([]byte(s.ChallengePassword), []byte(challenge)) == 0 {
- return nil, errors.New("invalid challenge password provided")
+ return errors.New("invalid challenge password provided")
}
- return []SignCSROption{}, nil
+ return nil
}
}
diff --git a/vendor/github.com/smallstep/certificates/authority/provisioner/sign_options.go b/vendor/github.com/smallstep/certificates/authority/provisioner/sign_options.go
index fc842c4..fec9b9f 100644
--- a/vendor/github.com/smallstep/certificates/authority/provisioner/sign_options.go
+++ b/vendor/github.com/smallstep/certificates/authority/provisioner/sign_options.go
@@ -5,10 +5,7 @@ import (
"crypto/ecdsa"
"crypto/ed25519"
"crypto/rsa"
- "crypto/sha256"
- "crypto/subtle"
"crypto/x509"
- "encoding/base64"
"encoding/json"
"net"
"net/http"
@@ -190,27 +187,6 @@ func (v dnsNamesValidator) Valid(req *x509.CertificateRequest) error {
return nil
}
-// dnsNamesSubsetValidator validates the DNS name SANs of a certificate request.
-type dnsNamesSubsetValidator []string
-
-// Valid checks that all DNS name SANs in the certificate request are present in
-// the allowed list of DNS names.
-func (v dnsNamesSubsetValidator) Valid(req *x509.CertificateRequest) error {
- if len(req.DNSNames) == 0 {
- return nil
- }
- allowed := make(map[string]struct{}, len(v))
- for _, s := range v {
- allowed[s] = struct{}{}
- }
- for _, s := range req.DNSNames {
- if _, ok := allowed[s]; !ok {
- return errs.Forbidden("certificate request contains unauthorized DNS names - got %v, allowed %v", req.DNSNames, v)
- }
- }
- return nil
-}
-
// ipAddressesValidator validates the IP addresses SAN of a certificate request.
type ipAddressesValidator []net.IP
@@ -323,19 +299,14 @@ func (v defaultSANsValidator) Valid(req *x509.CertificateRequest) (err error) {
// duration.
type profileDefaultDuration time.Duration
-// Modify sets the certificate NotBefore and NotAfter using the following order:
-// - From the SignOptions that we get from flags.
-// - From x509.Certificate that we get from the template.
-// - NotBefore from the current time with a backdate.
-// - NotAfter from NotBefore plus the duration in v.
func (v profileDefaultDuration) Modify(cert *x509.Certificate, so SignOptions) error {
var backdate time.Duration
- notBefore := timeOr(so.NotBefore.Time(), cert.NotBefore)
+ notBefore := so.NotBefore.Time()
if notBefore.IsZero() {
notBefore = now()
backdate = -1 * so.Backdate
}
- notAfter := timeOr(so.NotAfter.RelativeTime(notBefore), cert.NotAfter)
+ notAfter := so.NotAfter.RelativeTime(notBefore)
if notAfter.IsZero() {
if v != 0 {
notAfter = notBefore.Add(time.Duration(v))
@@ -356,17 +327,11 @@ type profileLimitDuration struct {
notBefore, notAfter time.Time
}
-// Modify sets the certificate NotBefore and NotAfter but limits the validity
-// period to the certificate to one that is superficially imposed.
-//
-// The expected NotBefore and NotAfter are set using the following order:
-// - From the SignOptions that we get from flags.
-// - From x509.Certificate that we get from the template.
-// - NotBefore from the current time with a backdate.
-// - NotAfter from NotBefore plus the duration v or the notAfter in v if lower.
+// Option returns an x509util option that limits the validity period of a
+// certificate to one that is superficially imposed.
func (v profileLimitDuration) Modify(cert *x509.Certificate, so SignOptions) error {
var backdate time.Duration
- notBefore := timeOr(so.NotBefore.Time(), cert.NotBefore)
+ notBefore := so.NotBefore.Time()
if notBefore.IsZero() {
notBefore = now()
backdate = -1 * so.Backdate
@@ -377,7 +342,7 @@ func (v profileLimitDuration) Modify(cert *x509.Certificate, so SignOptions) err
notBefore, v.notBefore)
}
- notAfter := timeOr(so.NotAfter.RelativeTime(notBefore), cert.NotAfter)
+ notAfter := so.NotAfter.RelativeTime(notBefore)
if notAfter.After(v.notAfter) {
return errs.Forbidden(
"requested certificate notAfter (%s) is after the expiration of the provisioning credential (%s)",
@@ -404,8 +369,8 @@ type validityValidator struct {
}
// newValidityValidator return a new validity validator.
-func newValidityValidator(minDur, maxDur time.Duration) *validityValidator {
- return &validityValidator{min: minDur, max: maxDur}
+func newValidityValidator(min, max time.Duration) *validityValidator {
+ return &validityValidator{min: min, max: max}
}
// Valid validates the certificate validity settings (notBefore/notAfter) and
@@ -527,46 +492,3 @@ func (o *provisionerExtensionOption) Modify(cert *x509.Certificate, _ SignOption
cert.ExtraExtensions = append(cert.ExtraExtensions, ext)
return nil
}
-
-// csrFingerprintValidator is a CertificateRequestValidator that checks the
-// fingerprint of the certificate request with the provided one.
-type csrFingerprintValidator string
-
-func (s csrFingerprintValidator) Valid(cr *x509.CertificateRequest) error {
- if s != "" {
- expected, err := base64.RawURLEncoding.DecodeString(string(s))
- if err != nil {
- return errs.ForbiddenErr(err, "error decoding fingerprint")
- }
- sum := sha256.Sum256(cr.Raw)
- if subtle.ConstantTimeCompare(expected, sum[:]) != 1 {
- return errs.Forbidden("certificate request fingerprint does not match %q", s)
- }
- }
- return nil
-}
-
-// SignCSROption is the interface used to collect extra options in the SignCSR
-// method of the SCEP authority.
-type SignCSROption any
-
-// TemplateDataModifier is an interface that allows to modify template data.
-type TemplateDataModifier interface {
- Modify(data x509util.TemplateData)
-}
-
-type templateDataModifier struct {
- fn func(x509util.TemplateData)
-}
-
-func (t *templateDataModifier) Modify(data x509util.TemplateData) {
- t.fn(data)
-}
-
-// TemplateDataModifierFunc returns a TemplateDataModifier with the given
-// function.
-func TemplateDataModifierFunc(fn func(data x509util.TemplateData)) TemplateDataModifier {
- return &templateDataModifier{
- fn: fn,
- }
-}
diff --git a/vendor/github.com/smallstep/certificates/authority/provisioner/sign_ssh_options.go b/vendor/github.com/smallstep/certificates/authority/provisioner/sign_ssh_options.go
index 512a8f0..ee74ded 100644
--- a/vendor/github.com/smallstep/certificates/authority/provisioner/sign_ssh_options.go
+++ b/vendor/github.com/smallstep/certificates/authority/provisioner/sign_ssh_options.go
@@ -44,13 +44,6 @@ type SSHCertOptionsValidator interface {
Valid(got SignSSHOptions) error
}
-// SSHPublicKeyValidator is the interface used to validate the public key of an
-// SSH certificate.
-type SSHPublicKeyValidator interface {
- SignOption
- Valid(got ssh.PublicKey) error
-}
-
// SignSSHOptions contains the options that can be passed to the SignSSH method.
type SignSSHOptions struct {
CertType string `json:"certType"`
@@ -283,14 +276,14 @@ func (v *sshCertValidityValidator) Valid(cert *ssh.Certificate, opts SignSSHOpti
return errs.BadRequest("ssh certificate validBefore cannot be before validAfter")
}
- var minDur, maxDur time.Duration
+ var min, max time.Duration
switch cert.CertType {
case ssh.UserCert:
- minDur = v.MinUserSSHCertDuration()
- maxDur = v.MaxUserSSHCertDuration()
+ min = v.MinUserSSHCertDuration()
+ max = v.MaxUserSSHCertDuration()
case ssh.HostCert:
- minDur = v.MinHostSSHCertDuration()
- maxDur = v.MaxHostSSHCertDuration()
+ min = v.MinHostSSHCertDuration()
+ max = v.MaxHostSSHCertDuration()
case 0:
return errs.BadRequest("ssh certificate type has not been set")
default:
@@ -302,10 +295,10 @@ func (v *sshCertValidityValidator) Valid(cert *ssh.Certificate, opts SignSSHOpti
dur := time.Duration(cert.ValidBefore-cert.ValidAfter) * time.Second
switch {
- case dur < minDur:
- return errs.Forbidden("requested duration of %s is less than minimum accepted duration for selected provisioner of %s", dur, minDur)
- case dur > maxDur+opts.Backdate:
- return errs.Forbidden("requested duration of %s is greater than maximum accepted duration for selected provisioner of %s", dur, maxDur+opts.Backdate)
+ case dur < min:
+ return errs.Forbidden("requested duration of %s is less than minimum accepted duration for selected provisioner of %s", dur, min)
+ case dur > max+opts.Backdate:
+ return errs.Forbidden("requested duration of %s is greater than maximum accepted duration for selected provisioner of %s", dur, max+opts.Backdate)
default:
return nil
}
diff --git a/vendor/github.com/smallstep/certificates/authority/provisioner/ssh_options.go b/vendor/github.com/smallstep/certificates/authority/provisioner/ssh_options.go
index def2ec7..e870ff3 100644
--- a/vendor/github.com/smallstep/certificates/authority/provisioner/ssh_options.go
+++ b/vendor/github.com/smallstep/certificates/authority/provisioner/ssh_options.go
@@ -5,8 +5,7 @@ import (
"strings"
"github.com/pkg/errors"
-
- "github.com/smallstep/cli-utils/step"
+ "go.step.sm/cli-utils/step"
"go.step.sm/crypto/sshutil"
"github.com/smallstep/certificates/authority/policy"
diff --git a/vendor/github.com/smallstep/certificates/authority/provisioner/timeduration.go b/vendor/github.com/smallstep/certificates/authority/provisioner/timeduration.go
index 39bbb19..7d19721 100644
--- a/vendor/github.com/smallstep/certificates/authority/provisioner/timeduration.go
+++ b/vendor/github.com/smallstep/certificates/authority/provisioner/timeduration.go
@@ -11,17 +11,6 @@ var now = func() time.Time {
return time.Now().UTC()
}
-// timeOr returns the first of its arguments that is not equal to the zero time.
-// This method can be replaced with cmp.Or when step-ca requires Go 1.22.
-func timeOr(ts ...time.Time) time.Time {
- for _, t := range ts {
- if !t.IsZero() {
- return t
- }
- }
- return time.Time{}
-}
-
// TimeDuration is a type that represents a time but the JSON unmarshaling can
// use a time using the RFC 3339 format or a time.Duration string. If a duration
// is used, the time will be set on the first call to TimeDuration.Time.
diff --git a/vendor/github.com/smallstep/certificates/authority/provisioner/webhook.go b/vendor/github.com/smallstep/certificates/authority/provisioner/webhook.go
index 2822418..05f972f 100644
--- a/vendor/github.com/smallstep/certificates/authority/provisioner/webhook.go
+++ b/vendor/github.com/smallstep/certificates/authority/provisioner/webhook.go
@@ -65,9 +65,6 @@ func (wc *WebhookController) Enrich(ctx context.Context, req *webhook.RequestBod
return err
}
if !resp.Allow {
- if resp.Error != nil {
- return resp.Error
- }
return ErrWebhookDenied
}
wc.TemplateData.SetWebhook(wh.Name, resp.Data)
@@ -104,9 +101,6 @@ func (wc *WebhookController) Authorize(ctx context.Context, req *webhook.Request
return err
}
if !resp.Allow {
- if resp.Error != nil {
- return resp.Error
- }
return ErrWebhookDenied
}
}
diff --git a/vendor/github.com/smallstep/certificates/authority/provisioner/wire/dpop_options.go b/vendor/github.com/smallstep/certificates/authority/provisioner/wire/dpop_options.go
deleted file mode 100644
index 010cd5e..0000000
--- a/vendor/github.com/smallstep/certificates/authority/provisioner/wire/dpop_options.go
+++ /dev/null
@@ -1,49 +0,0 @@
-package wire
-
-import (
- "bytes"
- "crypto"
- "errors"
- "fmt"
- "text/template"
-
- "go.step.sm/crypto/pemutil"
-)
-
-type DPOPOptions struct {
- // Public part of the signing key for DPoP access token in PEM format
- SigningKey []byte `json:"key"`
- // URI template for the URI the ACME client must call to fetch the DPoP challenge proof (an access token from wire-server)
- Target string `json:"target"`
-
- signingKey crypto.PublicKey
- target *template.Template
-}
-
-func (o *DPOPOptions) GetSigningKey() crypto.PublicKey {
- return o.signingKey
-}
-
-func (o *DPOPOptions) EvaluateTarget(deviceID string) (string, error) {
- if deviceID == "" {
- return "", errors.New("deviceID must not be empty")
- }
- buf := new(bytes.Buffer)
- if err := o.target.Execute(buf, struct{ DeviceID string }{DeviceID: deviceID}); err != nil {
- return "", fmt.Errorf("failed executing DPoP template: %w", err)
- }
- return buf.String(), nil
-}
-
-func (o *DPOPOptions) validateAndInitialize() (err error) {
- o.signingKey, err = pemutil.Parse(o.SigningKey)
- if err != nil {
- return fmt.Errorf("failed parsing key: %w", err)
- }
- o.target, err = template.New("DeviceID").Parse(o.Target)
- if err != nil {
- return fmt.Errorf("failed parsing DPoP template: %w", err)
- }
-
- return nil
-}
diff --git a/vendor/github.com/smallstep/certificates/authority/provisioner/wire/oidc_options.go b/vendor/github.com/smallstep/certificates/authority/provisioner/wire/oidc_options.go
deleted file mode 100644
index e9139ca..0000000
--- a/vendor/github.com/smallstep/certificates/authority/provisioner/wire/oidc_options.go
+++ /dev/null
@@ -1,179 +0,0 @@
-package wire
-
-import (
- "bytes"
- "context"
- "encoding/json"
- "errors"
- "fmt"
- "net/url"
- "text/template"
- "time"
-
- "github.com/coreos/go-oidc/v3/oidc"
- "go.step.sm/crypto/x509util"
-)
-
-type Provider struct {
- DiscoveryBaseURL string `json:"discoveryBaseUrl,omitempty"`
- IssuerURL string `json:"issuerUrl,omitempty"`
- AuthURL string `json:"authorizationUrl,omitempty"`
- TokenURL string `json:"tokenUrl,omitempty"`
- JWKSURL string `json:"jwksUrl,omitempty"`
- UserInfoURL string `json:"userInfoUrl,omitempty"`
- Algorithms []string `json:"signatureAlgorithms,omitempty"`
-}
-
-type Config struct {
- ClientID string `json:"clientId,omitempty"`
- SignatureAlgorithms []string `json:"signatureAlgorithms,omitempty"`
-
- // the properties below are only used for testing
- SkipClientIDCheck bool `json:"-"`
- SkipExpiryCheck bool `json:"-"`
- SkipIssuerCheck bool `json:"-"`
- InsecureSkipSignatureCheck bool `json:"-"`
- Now func() time.Time `json:"-"`
-}
-
-type OIDCOptions struct {
- Provider *Provider `json:"provider,omitempty"`
- Config *Config `json:"config,omitempty"`
- TransformTemplate string `json:"transform,omitempty"`
-
- target *template.Template
- transform *template.Template
- oidcProviderConfig *oidc.ProviderConfig
- provider *oidc.Provider
- verifier *oidc.IDTokenVerifier
-}
-
-func (o *OIDCOptions) GetVerifier(ctx context.Context) (*oidc.IDTokenVerifier, error) {
- if o.verifier == nil {
- switch {
- case o.Provider.DiscoveryBaseURL != "":
- // creates a new OIDC provider using automatic discovery and the default HTTP client
- provider, err := oidc.NewProvider(ctx, o.Provider.DiscoveryBaseURL)
- if err != nil {
- return nil, fmt.Errorf("failed creating new OIDC provider using discovery: %w", err)
- }
- o.provider = provider
- default:
- o.provider = o.oidcProviderConfig.NewProvider(ctx)
- }
-
- if o.provider == nil {
- return nil, errors.New("no OIDC provider available")
- }
-
- o.verifier = o.provider.Verifier(o.getConfig())
- }
-
- return o.verifier, nil
-}
-
-func (o *OIDCOptions) getConfig() *oidc.Config {
- if o == nil || o.Config == nil {
- return &oidc.Config{}
- }
-
- return &oidc.Config{
- ClientID: o.Config.ClientID,
- SupportedSigningAlgs: o.Config.SignatureAlgorithms,
- SkipClientIDCheck: o.Config.SkipClientIDCheck,
- SkipExpiryCheck: o.Config.SkipExpiryCheck,
- SkipIssuerCheck: o.Config.SkipIssuerCheck,
- Now: o.Config.Now,
- InsecureSkipSignatureCheck: o.Config.InsecureSkipSignatureCheck,
- }
-}
-
-const defaultTemplate = `{"name": "{{ .name }}", "preferred_username": "{{ .preferred_username }}"}`
-
-func (o *OIDCOptions) validateAndInitialize() (err error) {
- if o.Provider == nil {
- return errors.New("provider not set")
- }
- if o.Provider.IssuerURL == "" && o.Provider.DiscoveryBaseURL == "" {
- return errors.New("either OIDC discovery or issuer URL must be set")
- }
-
- if o.Provider.DiscoveryBaseURL == "" {
- o.oidcProviderConfig, err = toOIDCProviderConfig(o.Provider)
- if err != nil {
- return fmt.Errorf("failed creationg OIDC provider config: %w", err)
- }
- }
-
- o.target, err = template.New("DeviceID").Parse(o.Provider.IssuerURL)
- if err != nil {
- return fmt.Errorf("failed parsing OIDC template: %w", err)
- }
-
- o.transform, err = parseTransform(o.TransformTemplate)
- if err != nil {
- return fmt.Errorf("failed parsing OIDC transformation template: %w", err)
- }
-
- return nil
-}
-
-func parseTransform(transformTemplate string) (*template.Template, error) {
- if transformTemplate == "" {
- transformTemplate = defaultTemplate
- }
-
- return template.New("transform").Funcs(x509util.GetFuncMap()).Parse(transformTemplate)
-}
-
-func (o *OIDCOptions) EvaluateTarget(deviceID string) (string, error) {
- buf := new(bytes.Buffer)
- if err := o.target.Execute(buf, struct{ DeviceID string }{DeviceID: deviceID}); err != nil {
- return "", fmt.Errorf("failed executing OIDC template: %w", err)
- }
- return buf.String(), nil
-}
-
-func (o *OIDCOptions) Transform(v map[string]any) (map[string]any, error) {
- if o.transform == nil || v == nil {
- return v, nil
- }
- // TODO(hs): add support for extracting error message from template "fail" function?
- buf := new(bytes.Buffer)
- if err := o.transform.Execute(buf, v); err != nil {
- return nil, fmt.Errorf("failed executing OIDC transformation: %w", err)
- }
- var r map[string]any
- if err := json.Unmarshal(buf.Bytes(), &r); err != nil {
- return nil, fmt.Errorf("failed unmarshaling transformed OIDC token: %w", err)
- }
- // add original claims if not yet in the transformed result
- for key, value := range v {
- if _, ok := r[key]; !ok {
- r[key] = value
- }
- }
- return r, nil
-}
-
-func toOIDCProviderConfig(in *Provider) (*oidc.ProviderConfig, error) {
- issuerURL, err := url.Parse(in.IssuerURL)
- if err != nil {
- return nil, fmt.Errorf("failed parsing issuer URL: %w", err)
- }
- // Removes query params from the URL because we use it as a way to notify client about the actual OAuth ClientId
- // for this provisioner.
- // This URL is going to look like: "https://idp:5556/dex?clientid=foo"
- // If we don't trim the query params here i.e. 'clientid' then the idToken verification is going to fail because
- // the 'iss' claim of the idToken will be "https://idp:5556/dex"
- issuerURL.RawQuery = ""
- issuerURL.Fragment = ""
- return &oidc.ProviderConfig{
- IssuerURL: issuerURL.String(),
- AuthURL: in.AuthURL,
- TokenURL: in.TokenURL,
- UserInfoURL: in.UserInfoURL,
- JWKSURL: in.JWKSURL,
- Algorithms: in.Algorithms,
- }, nil
-}
diff --git a/vendor/github.com/smallstep/certificates/authority/provisioner/wire/wire_options.go b/vendor/github.com/smallstep/certificates/authority/provisioner/wire/wire_options.go
deleted file mode 100644
index 2ae5543..0000000
--- a/vendor/github.com/smallstep/certificates/authority/provisioner/wire/wire_options.go
+++ /dev/null
@@ -1,51 +0,0 @@
-package wire
-
-import (
- "errors"
- "fmt"
-)
-
-// Options holds the Wire ACME extension options
-type Options struct {
- OIDC *OIDCOptions `json:"oidc,omitempty"`
- DPOP *DPOPOptions `json:"dpop,omitempty"`
-}
-
-// GetOIDCOptions returns the OIDC options.
-func (o *Options) GetOIDCOptions() *OIDCOptions {
- if o == nil {
- return nil
- }
- return o.OIDC
-}
-
-// GetDPOPOptions returns the DPoP options.
-func (o *Options) GetDPOPOptions() *DPOPOptions {
- if o == nil {
- return nil
- }
- return o.DPOP
-}
-
-// Validate validates and initializes the Wire OIDC and DPoP options.
-//
-// TODO(hs): find a good way to perform this only once.
-func (o *Options) Validate() error {
- if oidc := o.GetOIDCOptions(); oidc != nil {
- if err := oidc.validateAndInitialize(); err != nil {
- return fmt.Errorf("failed initializing OIDC options: %w", err)
- }
- } else {
- return errors.New("no OIDC options available")
- }
-
- if dpop := o.GetDPOPOptions(); dpop != nil {
- if err := dpop.validateAndInitialize(); err != nil {
- return fmt.Errorf("failed initializing DPoP options: %w", err)
- }
- } else {
- return errors.New("no DPoP options available")
- }
-
- return nil
-}
diff --git a/vendor/github.com/smallstep/certificates/authority/provisioner/x5c.go b/vendor/github.com/smallstep/certificates/authority/provisioner/x5c.go
index e1a152f..9b1f2b0 100644
--- a/vendor/github.com/smallstep/certificates/authority/provisioner/x5c.go
+++ b/vendor/github.com/smallstep/certificates/authority/provisioner/x5c.go
@@ -21,10 +21,9 @@ import (
// x5cPayload extends jwt.Claims with step attributes.
type x5cPayload struct {
jose.Claims
- SANs []string `json:"sans,omitempty"`
- Step *stepPayload `json:"step,omitempty"`
- Confirmation *cnfPayload `json:"cnf,omitempty"`
- chains [][]*x509.Certificate
+ SANs []string `json:"sans,omitempty"`
+ Step *stepPayload `json:"step,omitempty"`
+ chains [][]*x509.Certificate
}
// X5C is the default provisioner, an entity that can sign tokens necessary for
@@ -234,12 +233,6 @@ func (p *X5C) AuthorizeSign(ctx context.Context, token string) ([]SignOption, er
}
}
- // Check the fingerprint of the certificate request if given.
- var fingerprint string
- if claims.Confirmation != nil {
- fingerprint = claims.Confirmation.Fingerprint
- }
-
return []SignOption{
self,
templateOptions,
@@ -250,7 +243,6 @@ func (p *X5C) AuthorizeSign(ctx context.Context, token string) ([]SignOption, er
x5cLeaf.NotBefore, x5cLeaf.NotAfter,
},
// validators
- csrFingerprintValidator(fingerprint),
commonNameValidator(claims.Subject),
newDefaultSANsValidator(ctx, claims.SANs),
defaultPublicKeyValidator{},
@@ -301,7 +293,7 @@ func (p *X5C) AuthorizeSSHSign(_ context.Context, token string) ([]SignOption, e
// Use options in the token.
if opts.CertType != "" {
if certType, err = sshutil.CertTypeFromString(opts.CertType); err != nil {
- return nil, errs.BadRequestErr(err, err.Error()) //nolint:govet // allow non-constant error messages
+ return nil, errs.BadRequestErr(err, err.Error())
}
}
if opts.KeyID != "" {
diff --git a/vendor/github.com/smallstep/certificates/authority/provisioners.go b/vendor/github.com/smallstep/certificates/authority/provisioners.go
index 390a318..1502ea2 100644
--- a/vendor/github.com/smallstep/certificates/authority/provisioners.go
+++ b/vendor/github.com/smallstep/certificates/authority/provisioners.go
@@ -11,8 +11,8 @@ import (
"github.com/pkg/errors"
- "github.com/smallstep/cli-utils/step"
- "github.com/smallstep/cli-utils/ui"
+ "go.step.sm/cli-utils/step"
+ "go.step.sm/cli-utils/ui"
"go.step.sm/crypto/jose"
"go.step.sm/linkedca"
@@ -201,7 +201,6 @@ func (a *Authority) generateProvisionerConfig(ctx context.Context) (provisioner.
AuthorizeRenewFunc: a.authorizeRenewFunc,
AuthorizeSSHRenewFunc: a.authorizeSSHRenewFunc,
WebhookClient: a.webhookClient,
- HTTPClient: a.httpClient,
SCEPKeyManager: a.scepKeyManager,
}, nil
}
@@ -427,25 +426,25 @@ func ValidateClaims(c *linkedca.Claims) error {
// ValidateDurations validates the Durations type.
func ValidateDurations(d *linkedca.Durations) error {
var (
- err error
- minDur, maxDur, def *provisioner.Duration
+ err error
+ min, max, def *provisioner.Duration
)
if d.Min != "" {
- minDur, err = provisioner.NewDuration(d.Min)
+ min, err = provisioner.NewDuration(d.Min)
if err != nil {
return admin.WrapError(admin.ErrorBadRequestType, err, "min duration '%s' is invalid", d.Min)
}
- if minDur.Value() < 0 {
+ if min.Value() < 0 {
return admin.WrapError(admin.ErrorBadRequestType, err, "min duration '%s' cannot be less than 0", d.Min)
}
}
if d.Max != "" {
- maxDur, err = provisioner.NewDuration(d.Max)
+ max, err = provisioner.NewDuration(d.Max)
if err != nil {
return admin.WrapError(admin.ErrorBadRequestType, err, "max duration '%s' is invalid", d.Max)
}
- if maxDur.Value() < 0 {
+ if max.Value() < 0 {
return admin.WrapError(admin.ErrorBadRequestType, err, "max duration '%s' cannot be less than 0", d.Max)
}
}
@@ -458,15 +457,15 @@ func ValidateDurations(d *linkedca.Durations) error {
return admin.WrapError(admin.ErrorBadRequestType, err, "default duration '%s' cannot be less than 0", d.Default)
}
}
- if d.Min != "" && d.Max != "" && minDur.Value() > maxDur.Value() {
+ if d.Min != "" && d.Max != "" && min.Value() > max.Value() {
return admin.NewError(admin.ErrorBadRequestType,
"min duration '%s' cannot be greater than max duration '%s'", d.Min, d.Max)
}
- if d.Min != "" && d.Default != "" && minDur.Value() > def.Value() {
+ if d.Min != "" && d.Default != "" && min.Value() > def.Value() {
return admin.NewError(admin.ErrorBadRequestType,
"min duration '%s' cannot be greater than default duration '%s'", d.Min, d.Default)
}
- if d.Default != "" && d.Max != "" && minDur.Value() > def.Value() {
+ if d.Default != "" && d.Max != "" && min.Value() > def.Value() {
return admin.NewError(admin.ErrorBadRequestType,
"default duration '%s' cannot be greater than max duration '%s'", d.Default, d.Max)
}
@@ -609,15 +608,15 @@ func provisionerWebhookToLinkedca(pwh *provisioner.Webhook) *linkedca.Webhook {
return lwh
}
-func durationsToCertificates(d *linkedca.Durations) (minDur, maxDur, def *provisioner.Duration, err error) {
+func durationsToCertificates(d *linkedca.Durations) (min, max, def *provisioner.Duration, err error) {
if d.Min != "" {
- minDur, err = provisioner.NewDuration(d.Min)
+ min, err = provisioner.NewDuration(d.Min)
if err != nil {
return nil, nil, nil, admin.WrapErrorISE(err, "error parsing minimum duration '%s'", d.Min)
}
}
if d.Max != "" {
- maxDur, err = provisioner.NewDuration(d.Max)
+ max, err = provisioner.NewDuration(d.Max)
if err != nil {
return nil, nil, nil, admin.WrapErrorISE(err, "error parsing maximum duration '%s'", d.Max)
}
@@ -919,8 +918,6 @@ func ProvisionerToCertificates(p *linkedca.Provisioner) (provisioner.Interface,
Domains: cfg.Domains,
Groups: cfg.Groups,
ListenAddress: cfg.ListenAddress,
- Scopes: cfg.Scopes,
- AuthParams: cfg.AuthParams,
Claims: claims,
Options: options,
}, nil
@@ -955,8 +952,6 @@ func ProvisionerToCertificates(p *linkedca.Provisioner) (provisioner.Interface,
ProjectIDs: cfg.ProjectIds,
DisableCustomSANs: cfg.DisableCustomSans,
DisableTrustOnFirstUse: cfg.DisableTrustOnFirstUse,
- DisableSSHCAUser: cfg.DisableSshCaUser,
- DisableSSHCAHost: cfg.DisableSshCaHost,
InstanceAge: instanceAge,
Claims: claims,
Options: options,
@@ -1071,8 +1066,6 @@ func ProvisionerToLinkedca(p provisioner.Interface) (*linkedca.Provisioner, erro
Groups: p.Groups,
ListenAddress: p.ListenAddress,
TenantId: p.TenantID,
- Scopes: p.Scopes,
- AuthParams: p.AuthParams,
},
},
},
@@ -1097,8 +1090,6 @@ func ProvisionerToLinkedca(p provisioner.Interface) (*linkedca.Provisioner, erro
ProjectIds: p.ProjectIDs,
DisableCustomSans: p.DisableCustomSANs,
DisableTrustOnFirstUse: p.DisableTrustOnFirstUse,
- DisableSshCaUser: p.DisableSSHCAUser,
- DisableSshCaHost: p.DisableSSHCAHost,
InstanceAge: p.InstanceAge.String(),
},
},
diff --git a/vendor/github.com/smallstep/certificates/authority/root.go b/vendor/github.com/smallstep/certificates/authority/root.go
index 0a6ee63..37038cf 100644
--- a/vendor/github.com/smallstep/certificates/authority/root.go
+++ b/vendor/github.com/smallstep/certificates/authority/root.go
@@ -57,26 +57,3 @@ func (a *Authority) GetFederation() (federation []*x509.Certificate, err error)
})
return
}
-
-// GetIntermediateCertificate return the intermediate certificate that issues
-// the leaf certificates in the CA.
-//
-// This method can return nil if the CA is configured with a Certificate
-// Authority Service (CAS) that does not implement the
-// CertificateAuthorityGetter interface.
-func (a *Authority) GetIntermediateCertificate() *x509.Certificate {
- if len(a.intermediateX509Certs) > 0 {
- return a.intermediateX509Certs[0]
- }
- return nil
-}
-
-// GetIntermediateCertificates returns a list of all intermediate certificates
-// configured. The first certificate in the list will be the issuer certificate.
-//
-// This method can return an empty list or nil if the CA is configured with a
-// Certificate Authority Service (CAS) that does not implement the
-// CertificateAuthorityGetter interface.
-func (a *Authority) GetIntermediateCertificates() []*x509.Certificate {
- return a.intermediateX509Certs
-}
diff --git a/vendor/github.com/smallstep/certificates/authority/ssh.go b/vendor/github.com/smallstep/certificates/authority/ssh.go
index b28aa15..55f4f4a 100644
--- a/vendor/github.com/smallstep/certificates/authority/ssh.go
+++ b/vendor/github.com/smallstep/certificates/authority/ssh.go
@@ -154,16 +154,12 @@ func (a *Authority) SignSSH(ctx context.Context, key ssh.PublicKey, opts provisi
func (a *Authority) signSSH(ctx context.Context, key ssh.PublicKey, opts provisioner.SignSSHOptions, signOpts ...provisioner.SignOption) (*ssh.Certificate, provisioner.Interface, error) {
var (
- certOptions []sshutil.Option
- mods []provisioner.SSHCertModifier
- validators []provisioner.SSHCertValidator
- keyValidators []provisioner.SSHPublicKeyValidator
+ certOptions []sshutil.Option
+ mods []provisioner.SSHCertModifier
+ validators []provisioner.SSHCertValidator
)
- // Validate given key and options
- if key == nil {
- return nil, nil, errs.BadRequest("ssh public key cannot be nil")
- }
+ // Validate given options.
if err := opts.Validate(); err != nil {
return nil, nil, err
}
@@ -187,10 +183,6 @@ func (a *Authority) signSSH(ctx context.Context, key ssh.PublicKey, opts provisi
case provisioner.SSHCertModifier:
mods = append(mods, o)
- // validate the ssh public key
- case provisioner.SSHPublicKeyValidator:
- keyValidators = append(keyValidators, o)
-
// validate the ssh.Certificate
case provisioner.SSHCertValidator:
validators = append(validators, o)
@@ -210,16 +202,6 @@ func (a *Authority) signSSH(ctx context.Context, key ssh.PublicKey, opts provisi
}
}
- // Validate public key
- for _, v := range keyValidators {
- if err := v.Valid(key); err != nil {
- return nil, nil, errs.ApplyOptions(
- errs.ForbiddenErr(err, err.Error()), //nolint:govet // allow non-constant error messages
- errs.WithKeyVal("signOptions", signOpts),
- )
- }
- }
-
// Simulated certificate request with request options.
cr := sshutil.CertificateRequest{
Type: opts.CertType,
@@ -231,7 +213,7 @@ func (a *Authority) signSSH(ctx context.Context, key ssh.PublicKey, opts provisi
// Call enriching webhooks
if err := a.callEnrichingWebhooksSSH(ctx, prov, webhookCtl, cr); err != nil {
return nil, prov, errs.ApplyOptions(
- errs.ForbiddenErr(err, err.Error()), //nolint:govet // allow non-constant error messages
+ errs.ForbiddenErr(err, err.Error()),
errs.WithKeyVal("signOptions", signOpts),
)
}
@@ -243,7 +225,7 @@ func (a *Authority) signSSH(ctx context.Context, key ssh.PublicKey, opts provisi
switch {
case errors.As(err, &te):
return nil, prov, errs.ApplyOptions(
- errs.BadRequestErr(err, err.Error()), //nolint:govet // allow non-constant error messages
+ errs.BadRequestErr(err, err.Error()),
errs.WithKeyVal("signOptions", signOpts),
)
case strings.HasPrefix(err.Error(), "error unmarshaling certificate"):
@@ -263,7 +245,7 @@ func (a *Authority) signSSH(ctx context.Context, key ssh.PublicKey, opts provisi
// Use SignSSHOptions to modify the certificate validity. It will be later
// checked or set if not defined.
if err := opts.ModifyValidity(certTpl); err != nil {
- return nil, prov, errs.BadRequestErr(err, err.Error()) //nolint:govet // allow non-constant error messages
+ return nil, prov, errs.BadRequestErr(err, err.Error())
}
// Use provisioner modifiers.
diff --git a/vendor/github.com/smallstep/certificates/authority/tls.go b/vendor/github.com/smallstep/certificates/authority/tls.go
index 320eb59..ebc9d0d 100644
--- a/vendor/github.com/smallstep/certificates/authority/tls.go
+++ b/vendor/github.com/smallstep/certificates/authority/tls.go
@@ -91,21 +91,6 @@ func withDefaultASN1DN(def *config.ASN1DN) provisioner.CertificateModifierFunc {
}
}
-// GetX509Signer returns a [crypto.Signer] implementation using the intermediate
-// key.
-//
-// This method can return a [NotImplementedError] if the CA is configured with a
-// Certificate Authority Service (CAS) that does not implement the
-// CertificateAuthoritySigner interface.
-//
-// [NotImplementedError]: https://pkg.go.dev/github.com/smallstep/certificates/cas/apiv1#NotImplementedError
-func (a *Authority) GetX509Signer() (crypto.Signer, error) {
- if s, ok := a.x509CAService.(casapi.CertificateAuthoritySigner); ok {
- return s.GetSigner()
- }
- return nil, casapi.NotImplementedError{}
-}
-
// Sign creates a signed certificate from a certificate signing request. It
// creates a new context.Context, and calls into SignWithContext.
//
@@ -197,7 +182,7 @@ func (a *Authority) signX509(ctx context.Context, csr *x509.CertificateRequest,
if err := a.callEnrichingWebhooksX509(ctx, prov, webhookCtl, attData, csr); err != nil {
return nil, prov, errs.ApplyOptions(
- errs.ForbiddenErr(err, err.Error()), //nolint:govet // allow non-constant error messages
+ errs.ForbiddenErr(err, err.Error()),
errs.WithKeyVal("csr", csr),
errs.WithKeyVal("signOptions", signOpts),
)
@@ -209,7 +194,7 @@ func (a *Authority) signX509(ctx context.Context, csr *x509.CertificateRequest,
switch {
case errors.As(err, &te):
return nil, prov, errs.ApplyOptions(
- errs.BadRequestErr(err, err.Error()), //nolint:govet // allow non-constant error messages
+ errs.BadRequestErr(err, err.Error()),
errs.WithKeyVal("csr", csr),
errs.WithKeyVal("signOptions", signOpts),
)
diff --git a/vendor/github.com/smallstep/certificates/cas/apiv1/services.go b/vendor/github.com/smallstep/certificates/cas/apiv1/services.go
index 37c5adb..00ecc2a 100644
--- a/vendor/github.com/smallstep/certificates/cas/apiv1/services.go
+++ b/vendor/github.com/smallstep/certificates/cas/apiv1/services.go
@@ -1,7 +1,6 @@
package apiv1
import (
- "crypto"
"crypto/x509"
"net/http"
"strings"
@@ -27,20 +26,13 @@ type CertificateAuthorityGetter interface {
GetCertificateAuthority(req *GetCertificateAuthorityRequest) (*GetCertificateAuthorityResponse, error)
}
-// CertificateAuthorityCreator is an interface implemented by a
+// CertificateAuthorityCreator is an interface implamented by a
// CertificateAuthorityService that has a method to create a new certificate
// authority.
type CertificateAuthorityCreator interface {
CreateCertificateAuthority(req *CreateCertificateAuthorityRequest) (*CreateCertificateAuthorityResponse, error)
}
-// CertificateAuthoritySigner is an optional interface implemented by a
-// CertificateAuthorityService that has a method that returns a [crypto.Signer]
-// using the same key used to issue certificates.
-type CertificateAuthoritySigner interface {
- GetSigner() (crypto.Signer, error)
-}
-
// SignatureAlgorithmGetter is an optional implementation in a crypto.Signer
// that returns the SignatureAlgorithm to use.
type SignatureAlgorithmGetter interface {
diff --git a/vendor/github.com/smallstep/certificates/cas/softcas/softcas.go b/vendor/github.com/smallstep/certificates/cas/softcas/softcas.go
index 1e590ef..dd96197 100644
--- a/vendor/github.com/smallstep/certificates/cas/softcas/softcas.go
+++ b/vendor/github.com/smallstep/certificates/cas/softcas/softcas.go
@@ -58,13 +58,6 @@ func (c *SoftCAS) Type() apiv1.Type {
return apiv1.SoftCAS
}
-// GetSigner implements [apiv1.CertificateAuthoritySigner] and returns a
-// [crypto.Signer] with the intermediate key.
-func (c *SoftCAS) GetSigner() (crypto.Signer, error) {
- _, signer, err := c.getCertSigner()
- return signer, err
-}
-
// CreateCertificate signs a new certificate using Golang or KMS crypto.
func (c *SoftCAS) CreateCertificate(req *apiv1.CreateCertificateRequest) (*apiv1.CreateCertificateResponse, error) {
switch {
diff --git a/vendor/github.com/smallstep/certificates/errs/error.go b/vendor/github.com/smallstep/certificates/errs/error.go
index f01cb4d..4ea5001 100644
--- a/vendor/github.com/smallstep/certificates/errs/error.go
+++ b/vendor/github.com/smallstep/certificates/errs/error.go
@@ -62,11 +62,6 @@ type ErrorResponse struct {
Message string `json:"message"`
}
-// Unwrap implements the Unwrap interface and returns the original error.
-func (e *Error) Unwrap() error {
- return e.Err
-}
-
// Cause implements the errors.Causer interface and returns the original error.
func (e *Error) Cause() error {
return e.Err
@@ -182,7 +177,7 @@ func StatusCodeError(code int, e error, opts ...Option) error {
}
}
-const (
+var (
seeLogs = "Please see the certificate authority logs for more info."
// BadRequestDefaultMsg 400 default msg
BadRequestDefaultMsg = "The request could not be completed; malformed or missing data. " + seeLogs
@@ -198,7 +193,7 @@ const (
NotImplementedDefaultMsg = "The requested method is not implemented by the certificate authority. " + seeLogs
)
-const (
+var (
// BadRequestPrefix is the prefix added to the bad request messages that are
// directly sent to the cli.
BadRequestPrefix = "The request could not be completed: "
diff --git a/vendor/github.com/smallstep/certificates/logging/handler.go b/vendor/github.com/smallstep/certificates/logging/handler.go
index e9823c6..701d631 100644
--- a/vendor/github.com/smallstep/certificates/logging/handler.go
+++ b/vendor/github.com/smallstep/certificates/logging/handler.go
@@ -14,14 +14,6 @@ import (
"github.com/smallstep/certificates/middleware/requestid"
)
-// Common headers used for identifying the originating IP address of a client
-// connecting to a web server through a proxy server
-var (
- trueClientIP = http.CanonicalHeaderKey("True-Client-IP")
- xRealIP = http.CanonicalHeaderKey("X-Real-IP")
- xForwardedFor = http.CanonicalHeaderKey("X-Forwarded-For")
-)
-
// LoggerHandler creates a logger handler
type LoggerHandler struct {
name string
@@ -36,23 +28,16 @@ type options struct {
// endpoint should only be logged at the TRACE level in the (expected) HTTP
// 200 case
onlyTraceHealthEndpoint bool
-
- // logRealIP determines if the real IP address of the client should be logged
- // instead of the IP address of the proxy
- logRealIP bool
}
// NewLoggerHandler returns the given http.Handler with the logger integrated.
func NewLoggerHandler(name string, logger *Logger, next http.Handler) http.Handler {
onlyTraceHealthEndpoint, _ := strconv.ParseBool(os.Getenv("STEP_LOGGER_ONLY_TRACE_HEALTH_ENDPOINT"))
- logRealIP, _ := strconv.ParseBool(os.Getenv("STEP_LOGGER_LOG_REAL_IP"))
-
return &LoggerHandler{
name: name,
logger: logger.GetImpl(),
options: options{
onlyTraceHealthEndpoint: onlyTraceHealthEndpoint,
- logRealIP: logRealIP,
},
next: next,
}
@@ -82,12 +67,9 @@ func (l *LoggerHandler) writeEntry(w ResponseLogger, r *http.Request, t time.Tim
}
// Remote hostname
- addr := r.RemoteAddr
- if l.options.logRealIP {
- addr = realIP(r)
- }
- if host, _, err := net.SplitHostPort(addr); err == nil {
- addr = host
+ addr, _, err := net.SplitHostPort(r.RemoteAddr)
+ if err != nil {
+ addr = r.RemoteAddr
}
// From https://github.com/gorilla/handlers
@@ -143,27 +125,3 @@ func sanitizeLogEntry(s string) string {
escaped := strings.ReplaceAll(s, "\n", "")
return strings.ReplaceAll(escaped, "\r", "")
}
-
-// realIP returns the real IP address of the client connecting to the server by
-// parsing either the True-Client-IP, X-Real-IP or the X-Forwarded-For headers
-// (in that order). If the headers are not set or set to an invalid IP, it
-// returns the RemoteAddr of the request.
-func realIP(r *http.Request) string {
- var ip string
-
- if tcip := r.Header.Get(trueClientIP); tcip != "" {
- ip = tcip
- } else if xrip := r.Header.Get(xRealIP); xrip != "" {
- ip = xrip
- } else if xff := r.Header.Get(xForwardedFor); xff != "" {
- i := strings.Index(xff, ",")
- if i == -1 {
- i = len(xff)
- }
- ip = xff[:i]
- }
- if ip == "" || net.ParseIP(ip) == nil {
- return r.RemoteAddr
- }
- return ip
-}
diff --git a/vendor/github.com/smallstep/certificates/policy/engine.go b/vendor/github.com/smallstep/certificates/policy/engine.go
index 0f9af0d..5645732 100644
--- a/vendor/github.com/smallstep/certificates/policy/engine.go
+++ b/vendor/github.com/smallstep/certificates/policy/engine.go
@@ -270,7 +270,7 @@ func (e *NamePolicyEngine) IsSSHCertificateAllowed(cert *ssh.Certificate) error
return e.validateNames(dnsNames, ips, emails, []*url.URL{}, principals)
}
-// splitSSHPrincipals splits SSH certificate principals into DNS names, emails and usernames.
+// splitPrincipals splits SSH certificate principals into DNS names, emails and usernames.
func splitSSHPrincipals(cert *ssh.Certificate) (dnsNames []string, ips []net.IP, emails, principals []string, err error) {
dnsNames = []string{}
ips = []net.IP{}
diff --git a/vendor/github.com/smallstep/certificates/scep/authority.go b/vendor/github.com/smallstep/certificates/scep/authority.go
index 256c540..00c58d8 100644
--- a/vendor/github.com/smallstep/certificates/scep/authority.go
+++ b/vendor/github.com/smallstep/certificates/scep/authority.go
@@ -241,7 +241,7 @@ func (a *Authority) DecryptPKIEnvelope(ctx context.Context, msg *PKIMessage) err
// SignCSR creates an x509.Certificate based on a CSR template and Cert Authority credentials
// returns a new PKIMessage with CertRep data
-func (a *Authority) SignCSR(ctx context.Context, csr *x509.CertificateRequest, msg *PKIMessage, signCSROpts ...provisioner.SignCSROption) (*PKIMessage, error) {
+func (a *Authority) SignCSR(ctx context.Context, csr *x509.CertificateRequest, msg *PKIMessage) (*PKIMessage, error) {
// TODO: intermediate storage of the request? In SCEP it's possible to request a csr/certificate
// to be signed, which can be performed asynchronously / out-of-band. In that case a client can
// poll for the status. It seems to be similar as what can happen in ACME, so might want to model
@@ -284,13 +284,6 @@ func (a *Authority) SignCSR(ctx context.Context, csr *x509.CertificateRequest, m
CommonName: csr.Subject.CommonName,
})
- // Apply CSR options. Currently only one option is defined.
- for _, o := range signCSROpts {
- if m, ok := o.(provisioner.TemplateDataModifier); ok {
- m.Modify(data)
- }
- }
-
// Get authorizations from the SCEP provisioner.
ctx = provisioner.NewContextWithMethod(ctx, provisioner.SignMethod)
signOps, err := p.AuthorizeSign(ctx, "")
@@ -513,7 +506,7 @@ func (a *Authority) GetCACaps(ctx context.Context) []string {
return caps
}
-func (a *Authority) ValidateChallenge(ctx context.Context, csr *x509.CertificateRequest, challenge, transactionID string) ([]provisioner.SignCSROption, error) {
+func (a *Authority) ValidateChallenge(ctx context.Context, csr *x509.CertificateRequest, challenge, transactionID string) error {
p := provisionerFromContext(ctx)
return p.ValidateChallenge(ctx, csr, challenge, transactionID)
}
diff --git a/vendor/github.com/smallstep/certificates/scep/provisioner.go b/vendor/github.com/smallstep/certificates/scep/provisioner.go
index 35821d8..3df4b36 100644
--- a/vendor/github.com/smallstep/certificates/scep/provisioner.go
+++ b/vendor/github.com/smallstep/certificates/scep/provisioner.go
@@ -20,7 +20,7 @@ type Provisioner interface {
GetDecrypter() (*x509.Certificate, crypto.Decrypter)
GetSigner() (*x509.Certificate, crypto.Signer)
GetContentEncryptionAlgorithm() int
- ValidateChallenge(ctx context.Context, csr *x509.CertificateRequest, challenge, transactionID string) ([]provisioner.SignCSROption, error)
+ ValidateChallenge(ctx context.Context, csr *x509.CertificateRequest, challenge, transactionID string) error
NotifySuccess(ctx context.Context, csr *x509.CertificateRequest, cert *x509.Certificate, transactionID string) error
NotifyFailure(ctx context.Context, csr *x509.CertificateRequest, transactionID string, errorCode int, errorDescription string) error
}
diff --git a/vendor/github.com/smallstep/certificates/scep/scep.go b/vendor/github.com/smallstep/certificates/scep/scep.go
index ec7fd05..da7e202 100644
--- a/vendor/github.com/smallstep/certificates/scep/scep.go
+++ b/vendor/github.com/smallstep/certificates/scep/scep.go
@@ -9,15 +9,6 @@ import (
smallscep "github.com/smallstep/scep"
)
-func init() {
- // enable the fallback X509 certificate parser to support parsing
- // Windows SCEP enrollment certificates that contain a critical
- // authority key identifier extension. Starting with Go 1.23 those
- // fail to be parsed by crypto/x509. Enabling the legacy fallback
- // parser is a workaround for that.
- pkcs7.SetFallbackLegacyX509CertificateParserEnabled(true)
-}
-
// FailInfoName models the name/value of failInfo
type FailInfoName smallscep.FailInfo
diff --git a/vendor/github.com/smallstep/certificates/templates/templates.go b/vendor/github.com/smallstep/certificates/templates/templates.go
index e58f5fb..2544b6e 100644
--- a/vendor/github.com/smallstep/certificates/templates/templates.go
+++ b/vendor/github.com/smallstep/certificates/templates/templates.go
@@ -9,9 +9,8 @@ import (
"github.com/Masterminds/sprig/v3"
"github.com/pkg/errors"
-
- "github.com/smallstep/cli-utils/fileutil"
- "github.com/smallstep/cli-utils/step"
+ "go.step.sm/cli-utils/fileutil"
+ "go.step.sm/cli-utils/step"
)
// TemplateType defines how a template will be written in disk.
diff --git a/vendor/github.com/smallstep/certificates/templates/values.go b/vendor/github.com/smallstep/certificates/templates/values.go
index f02ba47..aa158a9 100644
--- a/vendor/github.com/smallstep/certificates/templates/values.go
+++ b/vendor/github.com/smallstep/certificates/templates/values.go
@@ -108,10 +108,10 @@ var DefaultSSHTemplateData = map[string]string{
{{- end }}
{{- if or .User.GOOS "none" | eq "windows" }}
UserKnownHostsFile "{{.User.StepPath}}\ssh\known_hosts"
- ProxyCommand C:\Windows\System32\cmd.exe /c step ssh proxycommand{{- if .User.Context }} --context {{ .User.Context }}{{- end }}{{- if .User.Console}} --console {{- end }}{{- if .User.Provisioner }} --provisioner {{ .User.Provisioner }}{{- end }} %r %h %p
+ ProxyCommand C:\Windows\System32\cmd.exe /c step ssh proxycommand{{- if .User.Context }} --context {{ .User.Context }}{{- end }}{{- if .User.Provisioner }} --provisioner {{ .User.Provisioner }}{{- end }} %r %h %p
{{- else }}
UserKnownHostsFile "{{.User.StepPath}}/ssh/known_hosts"
- ProxyCommand step ssh proxycommand{{- if .User.Context }} --context {{ .User.Context }}{{- end }}{{- if .User.Console}} --console {{- end }}{{- if .User.Provisioner }} --provisioner {{ .User.Provisioner }}{{- end }} %r %h %p
+ ProxyCommand step ssh proxycommand{{- if .User.Context }} --context {{ .User.Context }}{{- end }}{{- if .User.Provisioner }} --provisioner {{ .User.Provisioner }}{{- end }} %r %h %p
{{- end }}
`,
diff --git a/vendor/github.com/smallstep/certificates/webhook/types.go b/vendor/github.com/smallstep/certificates/webhook/types.go
index c60de70..5e0e4d2 100644
--- a/vendor/github.com/smallstep/certificates/webhook/types.go
+++ b/vendor/github.com/smallstep/certificates/webhook/types.go
@@ -1,7 +1,6 @@
package webhook
import (
- "fmt"
"time"
"go.step.sm/crypto/sshutil"
@@ -10,19 +9,8 @@ import (
// ResponseBody is the body returned by webhook servers.
type ResponseBody struct {
- Data any `json:"data"`
- Allow bool `json:"allow"`
- Error *Error `json:"error,omitempty"`
-}
-
-// Error provides details explaining why the webhook was not permitted.
-type Error struct {
- Code string `json:"code"`
- Message string `json:"message"`
-}
-
-func (e *Error) Error() string {
- return fmt.Sprintf("%s (%s)", e.Message, e.Code)
+ Data any `json:"data"`
+ Allow bool `json:"allow"`
}
// X509CertificateRequest is the certificate request sent to webhook servers for
diff --git a/vendor/github.com/smallstep/cli-utils/LICENSE b/vendor/github.com/smallstep/cli-utils/LICENSE
deleted file mode 100644
index 261eeb9..0000000
--- a/vendor/github.com/smallstep/cli-utils/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/vendor/github.com/smallstep/cli-utils/command/command.go b/vendor/github.com/smallstep/cli-utils/command/command.go
deleted file mode 100644
index 5da6e85..0000000
--- a/vendor/github.com/smallstep/cli-utils/command/command.go
+++ /dev/null
@@ -1,45 +0,0 @@
-package command
-
-import (
- "os"
-
- "github.com/urfave/cli"
-
- "github.com/smallstep/cli-utils/step"
- "github.com/smallstep/cli-utils/usage"
-)
-
-var cmds []cli.Command
-var currentContext *cli.Context
-
-func init() {
- os.Unsetenv(step.IgnoreEnvVar)
- cmds = []cli.Command{
- usage.HelpCommand(),
- }
-}
-
-// Register adds the given command to the global list of commands.
-// It sets recursively the command Flags environment variables.
-func Register(c cli.Command) {
- step.SetEnvVar(&c)
- cmds = append(cmds, c)
-}
-
-// Retrieve returns all commands
-func Retrieve() []cli.Command {
- return cmds
-}
-
-// ActionFunc returns a cli.ActionFunc that stores the context.
-func ActionFunc(fn cli.ActionFunc) cli.ActionFunc {
- return func(ctx *cli.Context) error {
- currentContext = ctx
- return fn(ctx)
- }
-}
-
-// IsForce returns if the force flag was passed
-func IsForce() bool {
- return currentContext != nil && currentContext.Bool("force")
-}
diff --git a/vendor/github.com/smallstep/cli-utils/errs/errs.go b/vendor/github.com/smallstep/cli-utils/errs/errs.go
deleted file mode 100644
index 28ecf1e..0000000
--- a/vendor/github.com/smallstep/cli-utils/errs/errs.go
+++ /dev/null
@@ -1,330 +0,0 @@
-package errs
-
-import (
- "fmt"
- "os"
- "strings"
-
- "errors"
-
- pkge "github.com/pkg/errors"
- "github.com/urfave/cli"
-)
-
-// NewError returns a new Error for the given format and arguments
-func NewError(format string, args ...interface{}) error {
- return fmt.Errorf(format, args...)
-}
-
-// NewExitError returns an error that the urfave/cli package will handle and
-// will show the given error and exit with the given code.
-func NewExitError(err error, exitCode int) error {
- return cli.NewExitError(err, exitCode)
-}
-
-// Wrap returns a new error wrapped by the given error with the given message.
-// If the given error implements the errors.Cause interface, the base error is
-// used. If the given error is wrapped by a package name, the error wrapped
-// will be the string after the last colon.
-//
-// TODO: this should be refactored to use Go's wrap facilities.
-func Wrap(err error, format string, args ...interface{}) error {
- if err == nil {
- return nil
- }
- cause := pkge.Cause(err)
- if errors.Is(err, cause) {
- str := err.Error()
- if i := strings.LastIndexByte(str, ':'); i >= 0 {
- str = strings.TrimSpace(str[i:])
- return pkge.Wrapf(errors.New(str), format, args...)
- }
- }
- return pkge.Wrapf(cause, format, args...)
-}
-
-// InsecureCommand returns an error with a message saying that the current
-// command requires the insecure flag.
-func InsecureCommand(ctx *cli.Context) error {
- return fmt.Errorf("'%s %s' requires the '--insecure' flag", ctx.App.Name, ctx.Command.Name)
-}
-
-// EqualArguments returns an error saying that the given positional arguments
-// cannot be equal.
-func EqualArguments(ctx *cli.Context, arg1, arg2 string) error {
- return fmt.Errorf("positional arguments <%s> and <%s> cannot be equal in '%s'", arg1, arg2, usage(ctx))
-}
-
-// MissingArguments returns an error with a missing arguments message for the
-// given positional argument names.
-func MissingArguments(ctx *cli.Context, argNames ...string) error {
- switch len(argNames) {
- case 0:
- return fmt.Errorf("missing positional arguments in '%s'", usage(ctx))
- case 1:
- return fmt.Errorf("missing positional argument <%s> in '%s'", argNames[0], usage(ctx))
- default:
- args := make([]string, len(argNames))
- for i, name := range argNames {
- args[i] = "<" + name + ">"
- }
- return fmt.Errorf("missing positional arguments %s in '%s'", strings.Join(args, " "), usage(ctx))
- }
-}
-
-// NumberOfArguments returns nil if the number of positional arguments is
-// equal to the required one. It will return an appropriate error if they are
-// not.
-func NumberOfArguments(ctx *cli.Context, required int) error {
- n := ctx.NArg()
- switch {
- case n < required:
- return TooFewArguments(ctx)
- case n > required:
- return TooManyArguments(ctx)
- default:
- return nil
- }
-}
-
-// MinMaxNumberOfArguments returns nil if the number of positional arguments
-// between the min/max range. It will return an appropriate error if they are
-// not.
-func MinMaxNumberOfArguments(ctx *cli.Context, minNumber, maxNumber int) error {
- n := ctx.NArg()
- switch {
- case n < minNumber:
- return TooFewArguments(ctx)
- case n > maxNumber:
- return TooManyArguments(ctx)
- default:
- return nil
- }
-}
-
-// TooFewArguments returns an error with a few arguments were provided message.
-func TooFewArguments(ctx *cli.Context) error {
- return fmt.Errorf("not enough positional arguments were provided in '%s'", usage(ctx))
-}
-
-// TooManyArguments returns an error with a too many arguments were provided
-// message.
-func TooManyArguments(ctx *cli.Context) error {
- return fmt.Errorf("too many positional arguments were provided in '%s'", usage(ctx))
-}
-
-// InsecureArgument returns an error with the given argument requiring the
-// --insecure flag.
-func InsecureArgument(_ *cli.Context, name string) error {
- return fmt.Errorf("positional argument <%s> requires the '--insecure' flag", name)
-}
-
-// FlagValueInsecure returns an error with the given flag and value requiring
-// the --insecure flag.
-func FlagValueInsecure(_ *cli.Context, flag, value string) error {
- return fmt.Errorf("flag '--%s %s' requires the '--insecure' flag", flag, value)
-}
-
-// InvalidFlagValue returns an error with the given value being missing or
-// invalid for the given flag. Optionally it lists the given formatted options
-// at the end.
-func InvalidFlagValue(ctx *cli.Context, flag, value, options string) error {
- if options != "" {
- options = fmt.Sprintf("options are %s", options)
- }
-
- return InvalidFlagValueMsg(ctx, flag, value, options)
-}
-
-// InvalidFlagValueMsg returns an error with the given value being missing or
-// invalid for the given flag. Optionally it returns an error message to aid
-// in debugging.
-func InvalidFlagValueMsg(_ *cli.Context, flag, value, msg string) error {
- var format string
- if value == "" {
- format = fmt.Sprintf("missing value for flag '--%s'", flag)
- } else {
- format = fmt.Sprintf("invalid value '%s' for flag '--%s'", value, flag)
- }
-
- if msg == "" {
- return errors.New(format)
- }
-
- return errors.New(format + "; " + msg)
-}
-
-// IncompatibleFlag returns an error with the flag being incompatible with the
-// given value.
-func IncompatibleFlag(_ *cli.Context, flag, value string) error {
- return fmt.Errorf("flag '--%s' is incompatible with '%s'", flag, value)
-}
-
-// IncompatibleFlagWithFlag returns an error with the flag being incompatible with the
-// given value.
-func IncompatibleFlagWithFlag(_ *cli.Context, flag, withFlag string) error {
- return fmt.Errorf("flag '--%s' is incompatible with '--%s'", flag, withFlag)
-}
-
-// IncompatibleFlagValue returns an error with the flag being incompatible with the
-// given value.
-func IncompatibleFlagValue(_ *cli.Context, flag, incompatibleWith,
- incompatibleWithValue string) error {
- return fmt.Errorf("flag '--%s' is incompatible with flag '--%s %s'",
- flag, incompatibleWith, incompatibleWithValue)
-}
-
-// IncompatibleFlagValues returns an error with the flag being incompatible with the
-// given value.
-func IncompatibleFlagValues(ctx *cli.Context, flag, value, incompatibleWith,
- incompatibleWithValue string) error {
- return IncompatibleFlagValueWithFlagValue(ctx, flag, value, incompatibleWith,
- incompatibleWithValue, "")
-}
-
-// IncompatibleFlagValueWithFlagValue returns an error with the given value
-// being missing or invalid for the given flag. Optionally it lists the given
-// formatted options at the end.
-func IncompatibleFlagValueWithFlagValue(_ *cli.Context, flag, value,
- withFlag, withValue, options string) error {
- format := fmt.Sprintf("flag '--%s %s' is incompatible with flag '--%s %s'",
- flag, value, withFlag, withValue)
-
- if options == "" {
- return errors.New(format)
- }
-
- // TODO: check whether double space before options is intended
- return fmt.Errorf("%s\n\n Option(s): --%s %s", format, withFlag, options)
-}
-
-// RequiredFlag returns an error with the required flag message.
-func RequiredFlag(ctx *cli.Context, flag string) error {
- return fmt.Errorf("'%s %s' requires the '--%s' flag", ctx.App.HelpName,
- ctx.Command.Name, flag)
-}
-
-// RequiredWithFlag returns an error with the required flag message with another flag.
-func RequiredWithFlag(_ *cli.Context, flag, required string) error {
- return fmt.Errorf("flag '--%s' requires the '--%s' flag", flag, required)
-}
-
-// RequiredWithFlagValue returns an error with the required flag message.
-func RequiredWithFlagValue(_ *cli.Context, flag, value, required string) error {
- return fmt.Errorf("'--%s %s' requires the '--%s' flag", flag, value, required)
-}
-
-// RequiredWithProvisionerTypeFlag returns an error with the required flag message.
-func RequiredWithProvisionerTypeFlag(_ *cli.Context, provisionerType, required string) error {
- return fmt.Errorf("provisioner type '%s' requires the '--%s' flag", provisionerType, required)
-}
-
-// RequiredInsecureFlag returns an error with the given flag requiring the
-// insecure flag message.
-func RequiredInsecureFlag(_ *cli.Context, flag string) error {
- return fmt.Errorf("flag '--%s' requires the '--insecure' flag", flag)
-}
-
-// RequiredSubtleFlag returns an error with the given flag requiring the
-// subtle flag message..
-func RequiredSubtleFlag(_ *cli.Context, flag string) error {
- return fmt.Errorf("flag '--%s' requires the '--subtle' flag", flag)
-}
-
-// RequiredUnlessInsecureFlag returns an error with the required flag message unless
-// the insecure flag is used.
-func RequiredUnlessInsecureFlag(ctx *cli.Context, flag string) error {
- return RequiredUnlessFlag(ctx, flag, "insecure")
-}
-
-// RequiredUnlessFlag returns an error with the required flag message unless
-// the specified flag is used.
-func RequiredUnlessFlag(_ *cli.Context, flag, unlessFlag string) error {
- return fmt.Errorf("flag '--%s' is required unless the '--%s' flag is provided", flag, unlessFlag)
-}
-
-// RequiredUnlessSubtleFlag returns an error with the required flag message unless
-// the subtle flag is used.
-func RequiredUnlessSubtleFlag(ctx *cli.Context, flag string) error {
- return RequiredUnlessFlag(ctx, flag, "subtle")
-}
-
-// RequiredOrFlag returns an error with a list of flags being required messages.
-func RequiredOrFlag(_ *cli.Context, flags ...string) error {
- params := make([]string, len(flags))
- for i, flag := range flags {
- params[i] = "--" + flag
- }
- return fmt.Errorf("one of flag %s is required", strings.Join(params, " or "))
-}
-
-// RequiredWithOrFlag returns an error with a list of flags at least one of which
-// is required in conjunction with the last flag in the list.
-func RequiredWithOrFlag(_ *cli.Context, withFlag string, flags ...string) error {
- params := make([]string, len(flags))
- for i := 0; i < len(flags); i++ {
- params[i] = "--" + flags[i]
- }
- return fmt.Errorf("one of flag %s is required with flag --%s", strings.Join(params, " or "), withFlag)
-}
-
-// MinSizeFlag returns an error with a greater or equal message message for
-// the given flag and size.
-func MinSizeFlag(_ *cli.Context, flag, size string) error {
- return fmt.Errorf("flag '--%s' must be greater than or equal to %s", flag, size)
-}
-
-// MinSizeInsecureFlag returns an error with a requiring --insecure flag
-// message with the given flag an size.
-func MinSizeInsecureFlag(_ *cli.Context, flag, size string) error {
- return fmt.Errorf("flag '--%s' requires at least %s unless '--insecure' flag is provided", flag, size)
-}
-
-// MutuallyExclusiveFlags returns an error with mutually exclusive message for
-// the given flags.
-func MutuallyExclusiveFlags(_ *cli.Context, flag1, flag2 string) error {
- return fmt.Errorf("flag '--%s' and flag '--%s' are mutually exclusive", flag1, flag2)
-}
-
-// UnsupportedFlag returns an error with a message saying that the given flag is
-// not yet supported.
-func UnsupportedFlag(_ *cli.Context, flag string) error {
- return fmt.Errorf("flag '--%s' is not yet supported", flag)
-}
-
-// usage returns the command usage text if set or a default usage string.
-func usage(ctx *cli.Context) string {
- if ctx.Command.UsageText == "" {
- return fmt.Sprintf("%s %s [command options]", ctx.App.HelpName, ctx.Command.Name)
- }
- // keep just the first line and remove markdown
- lines := strings.Split(ctx.Command.UsageText, "\n")
- return strings.ReplaceAll(lines[0], "**", "")
-}
-
-// FileError is a wrapper for errors of the os package.
-func FileError(err error, filename string) error {
- if err == nil {
- return nil
- }
- var (
- pathErr *os.PathError
- linkErr *os.LinkError
- syscallErr *os.SyscallError
- )
- switch {
- case errors.As(err, &pathErr):
- return fmt.Errorf("%s %s failed: %w", pathErr.Op, pathErr.Path, pathErr.Err)
- case errors.As(err, &linkErr):
- return fmt.Errorf("%s %s %s failed: %w", linkErr.Op, linkErr.Old, linkErr.New, linkErr.Err)
- case errors.As(err, &syscallErr):
- return fmt.Errorf("%s failed: %w", syscallErr.Syscall, syscallErr.Err)
- default:
- return Wrap(err, "unexpected error on %s", filename)
- }
-}
-
-// FriendlyError is an interface for returning friendly error messages to the user.
-type FriendlyError interface {
- Message() string
-}
diff --git a/vendor/github.com/smallstep/cli-utils/fileutil/file.go b/vendor/github.com/smallstep/cli-utils/fileutil/file.go
deleted file mode 100644
index 04e00a2..0000000
--- a/vendor/github.com/smallstep/cli-utils/fileutil/file.go
+++ /dev/null
@@ -1,121 +0,0 @@
-package fileutil
-
-import (
- "os"
-
- "github.com/pkg/errors"
-)
-
-// File represents a wrapper on os.File that supports read, write, seek and
-// close methods, but they won't be called if an error occurred before.
-type File struct {
- File *os.File
- err error
-}
-
-// OpenFile calls os.OpenFile method and returns the os.File wrapped.
-func OpenFile(name string, flag int, perm os.FileMode) (*File, error) {
- f, err := os.OpenFile(name, flag, perm)
- if err != nil {
- return nil, FileError(err, name)
- }
- return &File{
- File: f,
- }, nil
-}
-
-// error writes f.err if it's not set and returns f.err.
-func (f *File) error(err error) error {
- if f.err == nil && err != nil {
- f.err = FileError(err, f.File.Name())
- }
- return f.err
-}
-
-// Close wraps `func (*os.File) Close` it will always call Close but the error
-// return will be the first error thrown if any.
-func (f *File) Close() error {
- return f.error(f.File.Close())
-}
-
-// Read wraps `func (*os.File) Read` but doesn't perform the operation if a
-// previous error was thrown.
-func (f *File) Read(b []byte) (n int, err error) {
- if f.err != nil {
- return 0, f.err
- }
- n, err = f.File.Read(b)
- return n, f.error(err)
-}
-
-// ReadAt wraps `func (*os.File) ReadAt` but doesn't perform the operation if a
-// previous error was thrown.
-func (f *File) ReadAt(b []byte, off int64) (n int, err error) {
- if f.err != nil {
- return 0, f.err
- }
- n, err = f.File.ReadAt(b, off)
- return n, f.error(err)
-}
-
-// Seek wraps `func (*os.File) Seek` but doesn't perform the operation if a
-// previous error was thrown.
-func (f *File) Seek(offset int64, whence int) (ret int64, err error) {
- if f.err != nil {
- return 0, f.err
- }
- ret, err = f.File.Seek(offset, whence)
- return ret, f.error(err)
-}
-
-// Write wraps `func (*os.File) Write` but doesn't perform the operation if a
-// previous error was thrown.
-func (f *File) Write(b []byte) (n int, err error) {
- if f.err != nil {
- return 0, f.err
- }
- n, err = f.File.Write(b)
- return n, f.error(err)
-}
-
-// WriteAt wraps `func (*os.File) WriteAt` but doesn't perform the operation if
-// a previous error was thrown.
-func (f *File) WriteAt(b []byte, off int64) (n int, err error) {
- if f.err != nil {
- return 0, f.err
- }
- n, err = f.File.WriteAt(b, off)
- return n, f.error(err)
-}
-
-// WriteString wraps `func (*os.File) WriteString` but doesn't perform the
-// operation if a previous error was thrown.
-func (f *File) WriteString(s string) (n int, err error) {
- if f.err != nil {
- return 0, f.err
- }
- n, err = f.File.WriteString(s)
- return n, f.error(err)
-}
-
-// FileError is a wrapper for errors of the os package.
-func FileError(err error, filename string) error {
- if err == nil {
- return nil
- }
- var (
- pathErr *os.PathError
- linkErr *os.LinkError
- syscallErr *os.SyscallError
- )
- switch {
- case errors.As(err, &pathErr):
- return errors.Errorf("%s %s failed: %v", pathErr.Op, pathErr.Path, pathErr.Err)
- case errors.As(err, &linkErr):
- return errors.Errorf("%s %s %s failed: %v", linkErr.Op, linkErr.Old, linkErr.New, linkErr.Err)
- case errors.As(err, &syscallErr):
- return errors.Errorf("%s failed: %v", syscallErr.Syscall, syscallErr.Err)
- default:
- return errors.Wrapf(err, "unexpected error on %s", filename)
- }
-}
diff --git a/vendor/github.com/smallstep/cli-utils/fileutil/write.go b/vendor/github.com/smallstep/cli-utils/fileutil/write.go
deleted file mode 100644
index ba8194b..0000000
--- a/vendor/github.com/smallstep/cli-utils/fileutil/write.go
+++ /dev/null
@@ -1,232 +0,0 @@
-package fileutil
-
-import (
- "bufio"
- "bytes"
- "fmt"
- "io"
- "os"
- "strings"
- "time"
-
- "github.com/pkg/errors"
-
- "github.com/smallstep/cli-utils/command"
- "github.com/smallstep/cli-utils/ui"
-)
-
-var (
- // ErrFileExists is the error returned if a file exists.
- ErrFileExists = errors.New("file exists")
-
- // ErrIsDir is the error returned if the file is a directory.
- ErrIsDir = errors.New("file is a directory")
-
- // SnippetHeader is the header of a step generated snippet in a
- // configuration file.
- SnippetHeader = "# autogenerated by step"
-
- // SnippetFooter is the header of a step generated snippet in a
- // configuration file.
- SnippetFooter = "# end"
-)
-
-// WriteFile wraps ioutil.WriteFile with a prompt to overwrite a file if
-// the file exists. It returns ErrFileExists if the user picks to not overwrite
-// the file. If force is set to true, the prompt will not be presented and the
-// file if exists will be overwritten.
-func WriteFile(filename string, data []byte, perm os.FileMode) error {
- if command.IsForce() {
- return os.WriteFile(filename, data, perm)
- }
-
- st, err := os.Stat(filename)
- if err != nil {
- if os.IsNotExist(err) {
- return os.WriteFile(filename, data, perm)
- }
- return errors.Wrapf(err, "error reading information for %s", filename)
- }
-
- if st.IsDir() {
- return ErrIsDir
- }
-
- str, err := ui.Prompt(fmt.Sprintf("Would you like to overwrite %s [y/n]", filename), ui.WithValidateYesNo())
- if err != nil {
- return err
- }
- switch strings.ToLower(strings.TrimSpace(str)) {
- case "y", "yes":
- case "n", "no":
- return ErrFileExists
- }
-
- return os.WriteFile(filename, data, perm)
-}
-
-// AppendNewLine appends the given data at the end of the file. If the last
-// character of the file does not contain an LF it prepends it to the data.
-func AppendNewLine(filename string, data []byte, perm os.FileMode) error {
- f, err := OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_APPEND, perm)
- if err != nil {
- return err
- }
- // Read last character
- if st, err := f.File.Stat(); err == nil && st.Size() != 0 {
- last := make([]byte, 1)
- f.Seek(-1, 2)
- f.Read(last)
- if last[0] != '\n' {
- f.WriteString("\n")
- }
- }
- f.Write(data)
- return f.Close()
-}
-
-func writeChunk(filename string, data []byte, hasHeaderFooter bool, header, footer string, perm os.FileMode) error {
- // Get file permissions
- if st, err := os.Stat(filename); err == nil {
- perm = st.Mode()
- } else if !os.IsNotExist(err) {
- return FileError(err, filename)
- }
-
- // Read file contents
- b, err := os.ReadFile(filename)
- if err != nil && !os.IsNotExist(err) {
- return FileError(err, filename)
- }
-
- // Detect previous configuration
- _, start, end := findConfiguration(bytes.NewReader(b), header, footer)
-
- // Replace previous configuration
- f, err := OpenFile(filename, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, perm)
- if err != nil {
- return FileError(err, filename)
- }
- if len(b) > 0 {
- f.Write(b[:start])
- if start == end {
- f.WriteString("\n")
- }
- }
- if !hasHeaderFooter {
- fmt.Fprintf(f, "%s @ %s\n", header, time.Now().UTC().Format(time.RFC3339))
- }
- f.Write(data)
- if !bytes.HasSuffix(data, []byte("\n")) {
- f.WriteString("\n")
- }
- if !hasHeaderFooter {
- f.WriteString(footer + "\n")
- }
- if len(b) > 0 {
- f.Write(b[end:])
- }
- return f.Close()
-}
-
-// WriteSnippet writes the given data into the given filename. It surrounds the
-// data with a default header and footer, and it will replace the previous one.
-func WriteSnippet(filename string, data []byte, perm os.FileMode) error {
- return writeChunk(filename, data, false, SnippetHeader, SnippetFooter, perm)
-}
-
-// PrependLine prepends the given line into the given filename and removes
-// other instances of the line in the file.
-func PrependLine(filename string, data []byte, perm os.FileMode) error {
- // Get file permissions
- if st, err := os.Stat(filename); err == nil {
- perm = st.Mode()
- } else if !os.IsNotExist(err) {
- return FileError(err, filename)
- }
-
- // Read file contents
- b, err := os.ReadFile(filename)
- if err != nil && !os.IsNotExist(err) {
- return FileError(err, filename)
- }
-
- line := string(data)
- result := []string{string(data)}
- for _, l := range strings.Split(string(b), "\n") {
- if l != "" && !strings.HasPrefix(l, line) {
- result = append(result, l)
- }
- }
-
- if err := os.WriteFile(filename, []byte(strings.Join(result, "\n")), perm); err != nil {
- return FileError(err, filename)
- }
- return nil
-}
-
-// RemoveLine removes a single line which contains the given substring from the
-// given file.
-func RemoveLine(filename, substr string) error {
- var perm os.FileMode
- // Get file permissions
- st, err := os.Stat(filename)
- switch {
- case os.IsNotExist(err):
- return nil
- case err != nil:
- return FileError(err, filename)
- default:
- perm = st.Mode()
- }
-
- // Read file contents
- b, err := os.ReadFile(filename)
- if err != nil && !os.IsNotExist(err) {
- return FileError(err, filename)
- }
-
- old := strings.Split(string(b), "\n")
- for i, l := range old {
- if !strings.Contains(l, substr) {
- continue
- }
- if err := os.WriteFile(filename, []byte(strings.Join(append(old[:i], old[i+1:]...), "\n")), perm); err != nil {
- return FileError(err, filename)
- }
- break
- }
-
- return nil
-}
-
-type offsetCounter struct {
- offset int64
-}
-
-func (o *offsetCounter) ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error) {
- advance, token, err = bufio.ScanLines(data, atEOF)
- o.offset += int64(advance)
- return
-}
-
-func findConfiguration(r io.Reader, header, footer string) (lines []string, start, end int64) {
- var inConfig bool
- counter := new(offsetCounter)
- scanner := bufio.NewScanner(r)
- scanner.Split(counter.ScanLines)
- for scanner.Scan() {
- line := scanner.Text()
- switch {
- case !inConfig && strings.HasPrefix(line, header):
- inConfig = true
- start = counter.offset - int64(len(line)+1)
- case inConfig && strings.HasPrefix(line, footer):
- return lines, start, counter.offset
- case inConfig:
- lines = append(lines, line)
- }
- }
-
- return lines, counter.offset, counter.offset
-}
diff --git a/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/LICENSE.txt b/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/LICENSE.txt
deleted file mode 100644
index 2885af3..0000000
--- a/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/LICENSE.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-Blackfriday is distributed under the Simplified BSD License:
-
-> Copyright © 2011 Russ Ross
-> All rights reserved.
->
-> Redistribution and use in source and binary forms, with or without
-> modification, are permitted provided that the following conditions
-> are met:
->
-> 1. Redistributions of source code must retain the above copyright
-> notice, this list of conditions and the following disclaimer.
->
-> 2. Redistributions in binary form must reproduce the above
-> copyright notice, this list of conditions and the following
-> disclaimer in the documentation and/or other materials provided with
-> the distribution.
->
-> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-> "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-> LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-> FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-> COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-> INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-> BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-> LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-> CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-> LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-> ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-> POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/README.md b/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/README.md
deleted file mode 100644
index 2e0db35..0000000
--- a/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/README.md
+++ /dev/null
@@ -1,283 +0,0 @@
-Blackfriday [![Build Status](https://travis-ci.org/russross/blackfriday.svg?branch=master)](https://travis-ci.org/russross/blackfriday)
-===========
-
-Blackfriday is a [Markdown][1] processor implemented in [Go][2]. It
-is paranoid about its input (so you can safely feed it user-supplied
-data), it is fast, it supports common extensions (tables, smart
-punctuation substitutions, etc.), and it is safe for all utf-8
-(unicode) input.
-
-HTML output is currently supported, along with Smartypants
-extensions.
-
-It started as a translation from C of [Sundown][3].
-
-
-Installation
-------------
-
-Blackfriday is compatible with any modern Go release. With Go 1.7 and git
-installed:
-
- go get gopkg.in/russross/blackfriday.v2
-
-will download, compile, and install the package into your `$GOPATH`
-directory hierarchy. Alternatively, you can achieve the same if you
-import it into a project:
-
- import "gopkg.in/russross/blackfriday.v2"
-
-and `go get` without parameters.
-
-
-Versions
---------
-
-Currently maintained and recommended version of Blackfriday is `v2`. It's being
-developed on its own branch: https://github.com/russross/blackfriday/v2. You
-should install and import it via [gopkg.in][6] at
-`gopkg.in/russross/blackfriday.v2`.
-
-Version 2 offers a number of improvements over v1:
-
-* Cleaned up API
-* A separate call to [`Parse`][4], which produces an abstract syntax tree for
- the document
-* Latest bug fixes
-* Flexibility to easily add your own rendering extensions
-
-Potential drawbacks:
-
-* Our benchmarks show v2 to be slightly slower than v1. Currently in the
- ballpark of around 15%.
-* API breakage. If you can't afford modifying your code to adhere to the new API
- and don't care too much about the new features, v2 is probably not for you.
-* Several bug fixes are trailing behind and still need to be forward-ported to
- v2. See issue [#348](https://github.com/russross/blackfriday/issues/348) for
- tracking.
-
-Usage
------
-
-For the most sensible markdown processing, it is as simple as getting your input
-into a byte slice and calling:
-
-```go
-output := blackfriday.Run(input)
-```
-
-Your input will be parsed and the output rendered with a set of most popular
-extensions enabled. If you want the most basic feature set, corresponding with
-the bare Markdown specification, use:
-
-```go
-output := blackfriday.Run(input, blackfriday.WithNoExtensions())
-```
-
-### Sanitize untrusted content
-
-Blackfriday itself does nothing to protect against malicious content. If you are
-dealing with user-supplied markdown, we recommend running Blackfriday's output
-through HTML sanitizer such as [Bluemonday][5].
-
-Here's an example of simple usage of Blackfriday together with Bluemonday:
-
-```go
-import (
- "github.com/microcosm-cc/bluemonday"
- "github.com/russross/blackfriday"
-)
-
-// ...
-unsafe := blackfriday.Run(input)
-html := bluemonday.UGCPolicy().SanitizeBytes(unsafe)
-```
-
-### Custom options
-
-If you want to customize the set of options, use `blackfriday.WithExtensions`,
-`blackfriday.WithRenderer` and `blackfriday.WithRefOverride`.
-
-You can also check out `blackfriday-tool` for a more complete example
-of how to use it. Download and install it using:
-
- go get github.com/russross/blackfriday-tool
-
-This is a simple command-line tool that allows you to process a
-markdown file using a standalone program. You can also browse the
-source directly on github if you are just looking for some example
-code:
-
-* <http://github.com/russross/blackfriday-tool>
-
-Note that if you have not already done so, installing
-`blackfriday-tool` will be sufficient to download and install
-blackfriday in addition to the tool itself. The tool binary will be
-installed in `$GOPATH/bin`. This is a statically-linked binary that
-can be copied to wherever you need it without worrying about
-dependencies and library versions.
-
-
-Features
---------
-
-All features of Sundown are supported, including:
-
-* **Compatibility**. The Markdown v1.0.3 test suite passes with
- the `--tidy` option. Without `--tidy`, the differences are
- mostly in whitespace and entity escaping, where blackfriday is
- more consistent and cleaner.
-
-* **Common extensions**, including table support, fenced code
- blocks, autolinks, strikethroughs, non-strict emphasis, etc.
-
-* **Safety**. Blackfriday is paranoid when parsing, making it safe
- to feed untrusted user input without fear of bad things
- happening. The test suite stress tests this and there are no
- known inputs that make it crash. If you find one, please let me
- know and send me the input that does it.
-
- NOTE: "safety" in this context means *runtime safety only*. In order to
- protect yourself against JavaScript injection in untrusted content, see
- [this example](https://github.com/russross/blackfriday#sanitize-untrusted-content).
-
-* **Fast processing**. It is fast enough to render on-demand in
- most web applications without having to cache the output.
-
-* **Thread safety**. You can run multiple parsers in different
- goroutines without ill effect. There is no dependence on global
- shared state.
-
-* **Minimal dependencies**. Blackfriday only depends on standard
- library packages in Go. The source code is pretty
- self-contained, so it is easy to add to any project, including
- Google App Engine projects.
-
-* **Standards compliant**. Output successfully validates using the
- W3C validation tool for HTML 4.01 and XHTML 1.0 Transitional.
-
-
-Extensions
-----------
-
-In addition to the standard markdown syntax, this package
-implements the following extensions:
-
-* **Intra-word emphasis supression**. The `_` character is
- commonly used inside words when discussing code, so having
- markdown interpret it as an emphasis command is usually the
- wrong thing. Blackfriday lets you treat all emphasis markers as
- normal characters when they occur inside a word.
-
-* **Tables**. Tables can be created by drawing them in the input
- using a simple syntax:
-
- ```
- Name | Age
- --------|------
- Bob | 27
- Alice | 23
- ```
-
-* **Fenced code blocks**. In addition to the normal 4-space
- indentation to mark code blocks, you can explicitly mark them
- and supply a language (to make syntax highlighting simple). Just
- mark it like this:
-
- ```go
- func getTrue() bool {
- return true
- }
- ```
-
- You can use 3 or more backticks to mark the beginning of the
- block, and the same number to mark the end of the block.
-
-* **Definition lists**. A simple definition list is made of a single-line
- term followed by a colon and the definition for that term.
-
- Cat
- : Fluffy animal everyone likes
-
- Internet
- : Vector of transmission for pictures of cats
-
- Terms must be separated from the previous definition by a blank line.
-
-* **Footnotes**. A marker in the text that will become a superscript number;
- a footnote definition that will be placed in a list of footnotes at the
- end of the document. A footnote looks like this:
-
- This is a footnote.[^1]
-
- [^1]: the footnote text.
-
-* **Autolinking**. Blackfriday can find URLs that have not been
- explicitly marked as links and turn them into links.
-
-* **Strikethrough**. Use two tildes (`~~`) to mark text that
- should be crossed out.
-
-* **Hard line breaks**. With this extension enabled newlines in the input
- translate into line breaks in the output. This extension is off by default.
-
-* **Smart quotes**. Smartypants-style punctuation substitution is
- supported, turning normal double- and single-quote marks into
- curly quotes, etc.
-
-* **LaTeX-style dash parsing** is an additional option, where `--`
- is translated into `&ndash;`, and `---` is translated into
- `&mdash;`. This differs from most smartypants processors, which
- turn a single hyphen into an ndash and a double hyphen into an
- mdash.
-
-* **Smart fractions**, where anything that looks like a fraction
- is translated into suitable HTML (instead of just a few special
- cases like most smartypant processors). For example, `4/5`
- becomes `<sup>4</sup>&frasl;<sub>5</sub>`, which renders as
- <sup>4</sup>&frasl;<sub>5</sub>.
-
-
-Other renderers
----------------
-
-Blackfriday is structured to allow alternative rendering engines. Here
-are a few of note:
-
-* [github_flavored_markdown](https://godoc.org/github.com/shurcooL/github_flavored_markdown):
- provides a GitHub Flavored Markdown renderer with fenced code block
- highlighting, clickable heading anchor links.
-
- It's not customizable, and its goal is to produce HTML output
- equivalent to the [GitHub Markdown API endpoint](https://developer.github.com/v3/markdown/#render-a-markdown-document-in-raw-mode),
- except the rendering is performed locally.
-
-* [markdownfmt](https://github.com/shurcooL/markdownfmt): like gofmt,
- but for markdown.
-
-* [LaTeX output](https://bitbucket.org/ambrevar/blackfriday-latex):
- renders output as LaTeX.
-
-
-Todo
-----
-
-* More unit testing
-* Improve unicode support. It does not understand all unicode
- rules (about what constitutes a letter, a punctuation symbol,
- etc.), so it may fail to detect word boundaries correctly in
- some instances. It is safe on all utf-8 input.
-
-
-License
--------
-
-[Blackfriday is distributed under the Simplified BSD License](LICENSE.txt)
-
-
- [1]: https://daringfireball.net/projects/markdown/ "Markdown"
- [2]: https://golang.org/ "Go Language"
- [3]: https://github.com/vmg/sundown "Sundown"
- [4]: https://godoc.org/gopkg.in/russross/blackfriday.v2#Parse "Parse func"
- [5]: https://github.com/microcosm-cc/bluemonday "Bluemonday"
- [6]: https://labix.org/gopkg.in "gopkg.in"
diff --git a/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/block.go b/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/block.go
deleted file mode 100644
index 918d656..0000000
--- a/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/block.go
+++ /dev/null
@@ -1,1559 +0,0 @@
-//
-// Blackfriday Markdown Processor
-// Available at http://github.com/russross/blackfriday
-//
-// Copyright © 2011 Russ Ross <russ@russross.com>.
-// Distributed under the Simplified BSD License.
-// See README.md for details.
-//
-
-//
-// Functions to parse block-level elements.
-//
-
-//nolint:gocritic,revive,ineffassign,gosimple,wastedassign // ignore blackfriday
-package blackfriday
-
-import (
- "bytes"
- "html"
- "regexp"
-
- "github.com/shurcooL/sanitized_anchor_name"
-)
-
-const (
- charEntity = "&(?:#x[a-f0-9]{1,8}|#[0-9]{1,8}|[a-z][a-z0-9]{1,31});"
- escapable = "[!\"#$%&'()*+,./:;<=>?@[\\\\\\]^_`{|}~-]"
-)
-
-var (
- reBackslashOrAmp = regexp.MustCompile("[\\&]")
- reEntityOrEscapedChar = regexp.MustCompile("(?i)\\\\" + escapable + "|" + charEntity)
-)
-
-// Parse block-level data.
-// Note: this function and many that it calls assume that
-// the input buffer ends with a newline.
-func (p *Markdown) block(data []byte) {
- // this is called recursively: enforce a maximum depth
- if p.nesting >= p.maxNesting {
- return
- }
- p.nesting++
-
- // parse out one block-level construct at a time
- for len(data) > 0 {
- // prefixed heading:
- //
- // # Heading 1
- // ## Heading 2
- // ...
- // ###### Heading 6
- if p.isPrefixHeading(data) {
- data = data[p.prefixHeading(data):]
- continue
- }
-
- // block of preformatted HTML:
- //
- // <div>
- // ...
- // </div>
- if data[0] == '<' {
- if i := p.html(data, true); i > 0 {
- data = data[i:]
- continue
- }
- }
-
- // title block
- //
- // % stuff
- // % more stuff
- // % even more stuff
- if p.extensions&Titleblock != 0 {
- if data[0] == '%' {
- if i := p.titleBlock(data, true); i > 0 {
- data = data[i:]
- continue
- }
- }
- }
-
- // blank lines. note: returns the # of bytes to skip
- if i := p.isEmpty(data); i > 0 {
- data = data[i:]
- continue
- }
-
- // indented code block:
- //
- // func max(a, b int) int {
- // if a > b {
- // return a
- // }
- // return b
- // }
- if p.codePrefix(data) > 0 {
- data = data[p.code(data):]
- continue
- }
-
- // fenced code block:
- //
- // ``` go
- // func fact(n int) int {
- // if n <= 1 {
- // return n
- // }
- // return n * fact(n-1)
- // }
- // ```
- if p.extensions&FencedCode != 0 {
- if i := p.fencedCodeBlock(data, true); i > 0 {
- data = data[i:]
- continue
- }
- }
-
- // horizontal rule:
- //
- // ------
- // or
- // ******
- // or
- // ______
- if p.isHRule(data) {
- p.addBlock(HorizontalRule, nil)
- var i int
- for i = 0; i < len(data) && data[i] != '\n'; i++ {
- }
- data = data[i:]
- continue
- }
-
- // block quote:
- //
- // > A big quote I found somewhere
- // > on the web
- if p.quotePrefix(data) > 0 {
- data = data[p.quote(data):]
- continue
- }
-
- // table:
- //
- // Name | Age | Phone
- // ------|-----|---------
- // Bob | 31 | 555-1234
- // Alice | 27 | 555-4321
- if p.extensions&Tables != 0 {
- if i := p.table(data); i > 0 {
- data = data[i:]
- continue
- }
- }
-
- // an itemized/unordered list:
- //
- // * Item 1
- // * Item 2
- //
- // also works with + or -
- if p.uliPrefix(data) > 0 {
- data = data[p.list(data, 0):]
- continue
- }
-
- // a numbered/ordered list:
- //
- // 1. Item 1
- // 2. Item 2
- if p.oliPrefix(data) > 0 {
- data = data[p.list(data, ListTypeOrdered):]
- continue
- }
-
- // definition lists:
- //
- // Term 1
- // : Definition a
- // : Definition b
- //
- // Term 2
- // : Definition c
- if p.extensions&DefinitionLists != 0 {
- if p.dliPrefix(data) > 0 {
- data = data[p.list(data, ListTypeDefinition):]
- continue
- }
- }
-
- // anything else must look like a normal paragraph
- // note: this finds underlined headings, too
- data = data[p.paragraph(data):]
- }
-
- p.nesting--
-}
-
-func (p *Markdown) addBlock(typ NodeType, content []byte) *Node {
- p.closeUnmatchedBlocks()
- container := p.addChild(typ, 0)
- container.content = content
- return container
-}
-
-func (p *Markdown) isPrefixHeading(data []byte) bool {
- if data[0] != '#' {
- return false
- }
-
- if p.extensions&SpaceHeadings != 0 {
- level := 0
- for level < 6 && level < len(data) && data[level] == '#' {
- level++
- }
- if level == len(data) || data[level] != ' ' {
- return false
- }
- }
- return true
-}
-
-func (p *Markdown) prefixHeading(data []byte) int {
- level := 0
- for level < 6 && level < len(data) && data[level] == '#' {
- level++
- }
- i := skipChar(data, level, ' ')
- end := skipUntilChar(data, i, '\n')
- skip := end
- id := ""
- if p.extensions&HeadingIDs != 0 {
- j, k := 0, 0
- // find start/end of heading id
- for j = i; j < end-1 && (data[j] != '{' || data[j+1] != '#'); j++ {
- }
- for k = j + 1; k < end && data[k] != '}'; k++ {
- }
- // extract heading id iff found
- if j < end && k < end {
- id = string(data[j+2 : k])
- end = j
- skip = k + 1
- for end > 0 && data[end-1] == ' ' {
- end--
- }
- }
- }
- for end > 0 && data[end-1] == '#' {
- if isBackslashEscaped(data, end-1) {
- break
- }
- end--
- }
- for end > 0 && data[end-1] == ' ' {
- end--
- }
- if end > i {
- if id == "" && p.extensions&AutoHeadingIDs != 0 {
- id = sanitized_anchor_name.Create(string(data[i:end]))
- }
- block := p.addBlock(Heading, data[i:end])
- block.HeadingID = id
- block.Level = level
- }
- return skip
-}
-
-func (p *Markdown) isUnderlinedHeading(data []byte) int {
- // test of level 1 heading
- if data[0] == '=' {
- i := skipChar(data, 1, '=')
- i = skipChar(data, i, ' ')
- if i < len(data) && data[i] == '\n' {
- return 1
- }
- return 0
- }
-
- // test of level 2 heading
- if data[0] == '-' {
- i := skipChar(data, 1, '-')
- i = skipChar(data, i, ' ')
- if i < len(data) && data[i] == '\n' {
- return 2
- }
- return 0
- }
-
- return 0
-}
-
-func (p *Markdown) titleBlock(data []byte, doRender bool) int {
- if data[0] != '%' {
- return 0
- }
- splitData := bytes.Split(data, []byte("\n"))
- var i int
- for idx, b := range splitData {
- if !bytes.HasPrefix(b, []byte("%")) {
- i = idx // - 1
- break
- }
- }
-
- data = bytes.Join(splitData[0:i], []byte("\n"))
- consumed := len(data)
- data = bytes.TrimPrefix(data, []byte("% "))
- data = bytes.Replace(data, []byte("\n% "), []byte("\n"), -1)
- block := p.addBlock(Heading, data)
- block.Level = 1
- block.IsTitleblock = true
-
- return consumed
-}
-
-func (p *Markdown) html(data []byte, doRender bool) int {
- var i, j int
-
- // identify the opening tag
- if data[0] != '<' {
- return 0
- }
- curtag, tagfound := p.htmlFindTag(data[1:])
-
- // handle special cases
- if !tagfound {
- // check for an HTML comment
- if size := p.htmlComment(data, doRender); size > 0 {
- return size
- }
-
- // check for an <hr> tag
- if size := p.htmlHr(data, doRender); size > 0 {
- return size
- }
-
- // no special case recognized
- return 0
- }
-
- // look for an unindented matching closing tag
- // followed by a blank line
- found := false
- /*
- closetag := []byte("\n</" + curtag + ">")
- j = len(curtag) + 1
- for !found {
- // scan for a closing tag at the beginning of a line
- if skip := bytes.Index(data[j:], closetag); skip >= 0 {
- j += skip + len(closetag)
- } else {
- break
- }
-
- // see if it is the only thing on the line
- if skip := p.isEmpty(data[j:]); skip > 0 {
- // see if it is followed by a blank line/eof
- j += skip
- if j >= len(data) {
- found = true
- i = j
- } else {
- if skip := p.isEmpty(data[j:]); skip > 0 {
- j += skip
- found = true
- i = j
- }
- }
- }
- }
- */
-
- // if not found, try a second pass looking for indented match
- // but not if tag is "ins" or "del" (following original Markdown.pl)
- if !found && curtag != "ins" && curtag != "del" {
- i = 1
- for i < len(data) {
- i++
- for i < len(data) && !(data[i-1] == '<' && data[i] == '/') {
- i++
- }
-
- if i+2+len(curtag) >= len(data) {
- break
- }
-
- j = p.htmlFindEnd(curtag, data[i-1:])
-
- if j > 0 {
- i += j - 1
- found = true
- break
- }
- }
- }
-
- if !found {
- return 0
- }
-
- // the end of the block has been found
- if doRender {
- // trim newlines
- end := i
- for end > 0 && data[end-1] == '\n' {
- end--
- }
- finalizeHTMLBlock(p.addBlock(HTMLBlock, data[:end]))
- }
-
- return i
-}
-
-func finalizeHTMLBlock(block *Node) {
- block.Literal = block.content
- block.content = nil
-}
-
-// HTML comment, lax form
-func (p *Markdown) htmlComment(data []byte, doRender bool) int {
- i := p.inlineHTMLComment(data)
- // needs to end with a blank line
- if j := p.isEmpty(data[i:]); j > 0 {
- size := i + j
- if doRender {
- // trim trailing newlines
- end := size
- for end > 0 && data[end-1] == '\n' {
- end--
- }
- block := p.addBlock(HTMLBlock, data[:end])
- finalizeHTMLBlock(block)
- }
- return size
- }
- return 0
-}
-
-// HR, which is the only self-closing block tag considered
-func (p *Markdown) htmlHr(data []byte, doRender bool) int {
- if len(data) < 4 {
- return 0
- }
- if data[0] != '<' || (data[1] != 'h' && data[1] != 'H') || (data[2] != 'r' && data[2] != 'R') {
- return 0
- }
- if data[3] != ' ' && data[3] != '/' && data[3] != '>' {
- // not an <hr> tag after all; at least not a valid one
- return 0
- }
- i := 3
- for i < len(data) && data[i] != '>' && data[i] != '\n' {
- i++
- }
- if i < len(data) && data[i] == '>' {
- i++
- if j := p.isEmpty(data[i:]); j > 0 {
- size := i + j
- if doRender {
- // trim newlines
- end := size
- for end > 0 && data[end-1] == '\n' {
- end--
- }
- finalizeHTMLBlock(p.addBlock(HTMLBlock, data[:end]))
- }
- return size
- }
- }
- return 0
-}
-
-func (p *Markdown) htmlFindTag(data []byte) (string, bool) {
- i := 0
- for i < len(data) && isalnum(data[i]) {
- i++
- }
- key := string(data[:i])
- if _, ok := blockTags[key]; ok {
- return key, true
- }
- return "", false
-}
-
-func (p *Markdown) htmlFindEnd(tag string, data []byte) int {
- // assume data[0] == '<' && data[1] == '/' already tested
- if tag == "hr" {
- return 2
- }
- // check if tag is a match
- closetag := []byte("</" + tag + ">")
- if !bytes.HasPrefix(data, closetag) {
- return 0
- }
- i := len(closetag)
-
- // check that the rest of the line is blank
- skip := 0
- if skip = p.isEmpty(data[i:]); skip == 0 {
- return 0
- }
- i += skip
- skip = 0
-
- if i >= len(data) {
- return i
- }
-
- if p.extensions&LaxHTMLBlocks != 0 {
- return i
- }
- if skip = p.isEmpty(data[i:]); skip == 0 {
- // following line must be blank
- return 0
- }
-
- return i + skip
-}
-
-func (*Markdown) isEmpty(data []byte) int {
- // it is okay to call isEmpty on an empty buffer
- if len(data) == 0 {
- return 0
- }
-
- var i int
- for i = 0; i < len(data) && data[i] != '\n'; i++ {
- if data[i] != ' ' && data[i] != '\t' {
- return 0
- }
- }
- if i < len(data) && data[i] == '\n' {
- i++
- }
- return i
-}
-
-func (*Markdown) isHRule(data []byte) bool {
- i := 0
-
- // skip up to three spaces
- for i < 3 && data[i] == ' ' {
- i++
- }
-
- // look at the hrule char
- if data[i] != '*' && data[i] != '-' && data[i] != '_' {
- return false
- }
- c := data[i]
-
- // the whole line must be the char or whitespace
- n := 0
- for i < len(data) && data[i] != '\n' {
- switch {
- case data[i] == c:
- n++
- case data[i] != ' ':
- return false
- }
- i++
- }
-
- return n >= 3
-}
-
-// isFenceLine checks if there's a fence line (e.g., ``` or ``` go) at the beginning of data,
-// and returns the end index if so, or 0 otherwise. It also returns the marker found.
-// If syntax is not nil, it gets set to the syntax specified in the fence line.
-func isFenceLine(data []byte, syntax *string, oldmarker string) (end int, marker string) {
- i, size := 0, 0
-
- // skip up to three spaces
- for i < len(data) && i < 3 && data[i] == ' ' {
- i++
- }
-
- // check for the marker characters: ~ or `
- if i >= len(data) {
- return 0, ""
- }
- if data[i] != '~' && data[i] != '`' {
- return 0, ""
- }
-
- c := data[i]
-
- // the whole line must be the same char or whitespace
- for i < len(data) && data[i] == c {
- size++
- i++
- }
-
- // the marker char must occur at least 3 times
- if size < 3 {
- return 0, ""
- }
- marker = string(data[i-size : i])
-
- // if this is the end marker, it must match the beginning marker
- if oldmarker != "" && marker != oldmarker {
- return 0, ""
- }
-
- // TODO(shurcooL): It's probably a good idea to simplify the 2 code paths here
- // into one, always get the syntax, and discard it if the caller doesn't care.
- if syntax != nil {
- syn := 0
- i = skipChar(data, i, ' ')
-
- if i >= len(data) {
- if i == len(data) {
- return i, marker
- }
- return 0, ""
- }
-
- syntaxStart := i
-
- if data[i] == '{' {
- i++
- syntaxStart++
-
- for i < len(data) && data[i] != '}' && data[i] != '\n' {
- syn++
- i++
- }
-
- if i >= len(data) || data[i] != '}' {
- return 0, ""
- }
-
- // strip all whitespace at the beginning and the end
- // of the {} block
- for syn > 0 && isspace(data[syntaxStart]) {
- syntaxStart++
- syn--
- }
-
- for syn > 0 && isspace(data[syntaxStart+syn-1]) {
- syn--
- }
-
- i++
- } else {
- for i < len(data) && !isspace(data[i]) {
- syn++
- i++
- }
- }
-
- *syntax = string(data[syntaxStart : syntaxStart+syn])
- }
-
- i = skipChar(data, i, ' ')
- if i >= len(data) || data[i] != '\n' {
- if i == len(data) {
- return i, marker
- }
- return 0, ""
- }
- return i + 1, marker // Take newline into account.
-}
-
-// fencedCodeBlock returns the end index if data contains a fenced code block at the beginning,
-// or 0 otherwise. It writes to out if doRender is true, otherwise it has no side effects.
-// If doRender is true, a final newline is mandatory to recognize the fenced code block.
-func (p *Markdown) fencedCodeBlock(data []byte, doRender bool) int {
- var syntax string
- beg, marker := isFenceLine(data, &syntax, "")
- if beg == 0 || beg >= len(data) {
- return 0
- }
-
- var work bytes.Buffer
- work.Write([]byte(syntax))
- work.WriteByte('\n')
-
- for {
- // safe to assume beg < len(data)
-
- // check for the end of the code block
- fenceEnd, _ := isFenceLine(data[beg:], nil, marker)
- if fenceEnd != 0 {
- beg += fenceEnd
- break
- }
-
- // copy the current line
- end := skipUntilChar(data, beg, '\n') + 1
-
- // did we reach the end of the buffer without a closing marker?
- if end >= len(data) {
- return 0
- }
-
- // verbatim copy to the working buffer
- if doRender {
- work.Write(data[beg:end])
- }
- beg = end
- }
-
- if doRender {
- block := p.addBlock(CodeBlock, work.Bytes()) // TODO: get rid of temp buffer
- block.IsFenced = true
- finalizeCodeBlock(block)
- }
-
- return beg
-}
-
-func unescapeChar(str []byte) []byte {
- if str[0] == '\\' {
- return []byte{str[1]}
- }
- return []byte(html.UnescapeString(string(str)))
-}
-
-func unescapeString(str []byte) []byte {
- if reBackslashOrAmp.Match(str) {
- return reEntityOrEscapedChar.ReplaceAllFunc(str, unescapeChar)
- }
- return str
-}
-
-func finalizeCodeBlock(block *Node) {
- if block.IsFenced {
- newlinePos := bytes.IndexByte(block.content, '\n')
- firstLine := block.content[:newlinePos]
- rest := block.content[newlinePos+1:]
- block.Info = unescapeString(bytes.Trim(firstLine, "\n"))
- block.Literal = rest
- } else {
- block.Literal = block.content
- }
- block.content = nil
-}
-
-func (p *Markdown) table(data []byte) int {
- table := p.addBlock(Table, nil)
- i, columns := p.tableHeader(data)
- if i == 0 {
- p.tip = table.Parent
- table.Unlink()
- return 0
- }
-
- p.addBlock(TableBody, nil)
-
- for i < len(data) {
- pipes, rowStart := 0, i
- for ; i < len(data) && data[i] != '\n'; i++ {
- if data[i] == '|' {
- pipes++
- }
- }
-
- if pipes == 0 {
- i = rowStart
- break
- }
-
- // include the newline in data sent to tableRow
- if i < len(data) && data[i] == '\n' {
- i++
- }
- p.tableRow(data[rowStart:i], columns, false)
- }
-
- return i
-}
-
-// check if the specified position is preceded by an odd number of backslashes
-func isBackslashEscaped(data []byte, i int) bool {
- backslashes := 0
- for i-backslashes-1 >= 0 && data[i-backslashes-1] == '\\' {
- backslashes++
- }
- return backslashes&1 == 1
-}
-
-func (p *Markdown) tableHeader(data []byte) (size int, columns []CellAlignFlags) {
- i := 0
- colCount := 1
- for i = 0; i < len(data) && data[i] != '\n'; i++ {
- if data[i] == '|' && !isBackslashEscaped(data, i) {
- colCount++
- }
- }
-
- // doesn't look like a table header
- if colCount == 1 {
- return
- }
-
- // include the newline in the data sent to tableRow
- j := i
- if j < len(data) && data[j] == '\n' {
- j++
- }
- header := data[:j]
-
- // column count ignores pipes at beginning or end of line
- if data[0] == '|' {
- colCount--
- }
- if i > 2 && data[i-1] == '|' && !isBackslashEscaped(data, i-1) {
- colCount--
- }
-
- columns = make([]CellAlignFlags, colCount)
-
- // move on to the header underline
- i++
- if i >= len(data) {
- return
- }
-
- if data[i] == '|' && !isBackslashEscaped(data, i) {
- i++
- }
- i = skipChar(data, i, ' ')
-
- // each column header is of form: / *:?-+:? *|/ with # dashes + # colons >= 3
- // and trailing | optional on last column
- col := 0
- for i < len(data) && data[i] != '\n' {
- dashes := 0
-
- if data[i] == ':' {
- i++
- columns[col] |= TableAlignmentLeft
- dashes++
- }
- for i < len(data) && data[i] == '-' {
- i++
- dashes++
- }
- if i < len(data) && data[i] == ':' {
- i++
- columns[col] |= TableAlignmentRight
- dashes++
- }
- for i < len(data) && data[i] == ' ' {
- i++
- }
- if i == len(data) {
- return
- }
- // end of column test is messy
- switch {
- case dashes < 3:
- // not a valid column
- return
-
- case data[i] == '|' && !isBackslashEscaped(data, i):
- // marker found, now skip past trailing whitespace
- col++
- i++
- for i < len(data) && data[i] == ' ' {
- i++
- }
-
- // trailing junk found after last column
- if col >= colCount && i < len(data) && data[i] != '\n' {
- return
- }
-
- case (data[i] != '|' || isBackslashEscaped(data, i)) && col+1 < colCount:
- // something else found where marker was required
- return
-
- case data[i] == '\n':
- // marker is optional for the last column
- col++
-
- default:
- // trailing junk found after last column
- return
- }
- }
- if col != colCount {
- return
- }
-
- p.addBlock(TableHead, nil)
- p.tableRow(header, columns, true)
- size = i
- if size < len(data) && data[size] == '\n' {
- size++
- }
- return
-}
-
-func (p *Markdown) tableRow(data []byte, columns []CellAlignFlags, header bool) {
- p.addBlock(TableRow, nil)
- i, col := 0, 0
-
- if data[i] == '|' && !isBackslashEscaped(data, i) {
- i++
- }
-
- for col = 0; col < len(columns) && i < len(data); col++ {
- for i < len(data) && data[i] == ' ' {
- i++
- }
-
- cellStart := i
-
- for i < len(data) && (data[i] != '|' || isBackslashEscaped(data, i)) && data[i] != '\n' {
- i++
- }
-
- cellEnd := i
-
- // skip the end-of-cell marker, possibly taking us past end of buffer
- i++
-
- for cellEnd > cellStart && cellEnd-1 < len(data) && data[cellEnd-1] == ' ' {
- cellEnd--
- }
-
- cell := p.addBlock(TableCell, data[cellStart:cellEnd])
- cell.IsHeader = header
- cell.Align = columns[col]
- }
-
- // pad it out with empty columns to get the right number
- for ; col < len(columns); col++ {
- cell := p.addBlock(TableCell, nil)
- cell.IsHeader = header
- cell.Align = columns[col]
- }
-
- // silently ignore rows with too many cells
-}
-
-// returns blockquote prefix length
-func (p *Markdown) quotePrefix(data []byte) int {
- i := 0
- for i < 3 && i < len(data) && data[i] == ' ' {
- i++
- }
- if i < len(data) && data[i] == '>' {
- if i+1 < len(data) && data[i+1] == ' ' {
- return i + 2
- }
- return i + 1
- }
- return 0
-}
-
-// blockquote ends with at least one blank line
-// followed by something without a blockquote prefix
-func (p *Markdown) terminateBlockquote(data []byte, beg, end int) bool {
- if p.isEmpty(data[beg:]) <= 0 {
- return false
- }
- if end >= len(data) {
- return true
- }
- return p.quotePrefix(data[end:]) == 0 && p.isEmpty(data[end:]) == 0
-}
-
-// parse a blockquote fragment
-func (p *Markdown) quote(data []byte) int {
- block := p.addBlock(BlockQuote, nil)
- var raw bytes.Buffer
- beg, end := 0, 0
- for beg < len(data) {
- end = beg
- // Step over whole lines, collecting them. While doing that, check for
- // fenced code and if one's found, incorporate it altogether,
- // irregardless of any contents inside it
- for end < len(data) && data[end] != '\n' {
- if p.extensions&FencedCode != 0 {
- if i := p.fencedCodeBlock(data[end:], false); i > 0 {
- // -1 to compensate for the extra end++ after the loop:
- end += i - 1
- break
- }
- }
- end++
- }
- if end < len(data) && data[end] == '\n' {
- end++
- }
- if pre := p.quotePrefix(data[beg:]); pre > 0 {
- // skip the prefix
- beg += pre
- } else if p.terminateBlockquote(data, beg, end) {
- break
- }
- // this line is part of the blockquote
- raw.Write(data[beg:end])
- beg = end
- }
- p.block(raw.Bytes())
- p.finalize(block)
- return end
-}
-
-// returns prefix length for block code
-func (p *Markdown) codePrefix(data []byte) int {
- if len(data) >= 1 && data[0] == '\t' {
- return 1
- }
- if len(data) >= 4 && data[0] == ' ' && data[1] == ' ' && data[2] == ' ' && data[3] == ' ' {
- return 4
- }
- return 0
-}
-
-func (p *Markdown) code(data []byte) int {
- var work bytes.Buffer
-
- i := 0
- for i < len(data) {
- beg := i
- for i < len(data) && data[i] != '\n' {
- i++
- }
- if i < len(data) && data[i] == '\n' {
- i++
- }
-
- blankline := p.isEmpty(data[beg:i]) > 0
- if pre := p.codePrefix(data[beg:i]); pre > 0 {
- beg += pre
- } else if !blankline {
- // non-empty, non-prefixed line breaks the pre
- i = beg
- break
- }
-
- // verbatim copy to the working buffer
- if blankline {
- work.WriteByte('\n')
- } else {
- work.Write(data[beg:i])
- }
- }
-
- // trim all the \n off the end of work
- workbytes := work.Bytes()
- eol := len(workbytes)
- for eol > 0 && workbytes[eol-1] == '\n' {
- eol--
- }
- if eol != len(workbytes) {
- work.Truncate(eol)
- }
-
- work.WriteByte('\n')
-
- block := p.addBlock(CodeBlock, work.Bytes()) // TODO: get rid of temp buffer
- block.IsFenced = false
- finalizeCodeBlock(block)
-
- return i
-}
-
-// returns unordered list item prefix
-func (p *Markdown) uliPrefix(data []byte) int {
- i := 0
- // start with up to 3 spaces
- for i < len(data) && i < 3 && data[i] == ' ' {
- i++
- }
- if i >= len(data)-1 {
- return 0
- }
- // need one of {'*', '+', '-'} followed by a space or a tab
- if (data[i] != '*' && data[i] != '+' && data[i] != '-') ||
- (data[i+1] != ' ' && data[i+1] != '\t') {
- return 0
- }
- return i + 2
-}
-
-// returns ordered list item prefix
-func (p *Markdown) oliPrefix(data []byte) int {
- i := 0
-
- // start with up to 3 spaces
- for i < 3 && i < len(data) && data[i] == ' ' {
- i++
- }
-
- // count the digits
- start := i
- for i < len(data) && data[i] >= '0' && data[i] <= '9' {
- i++
- }
- if start == i || i >= len(data)-1 {
- return 0
- }
-
- // we need >= 1 digits followed by a dot and a space or a tab
- if data[i] != '.' || !(data[i+1] == ' ' || data[i+1] == '\t') {
- return 0
- }
- return i + 2
-}
-
-// returns definition list item prefix
-func (p *Markdown) dliPrefix(data []byte) int {
- if len(data) < 2 {
- return 0
- }
- i := 0
- // need a ':' followed by a space or a tab
- if data[i] != ':' || !(data[i+1] == ' ' || data[i+1] == '\t') {
- return 0
- }
- for i < len(data) && data[i] == ' ' {
- i++
- }
- return i + 2
-}
-
-// parse ordered or unordered list block
-func (p *Markdown) list(data []byte, flags ListType) int {
- i := 0
- flags |= ListItemBeginningOfList
- block := p.addBlock(List, nil)
- block.ListFlags = flags
- block.Tight = true
-
- for i < len(data) {
- skip := p.listItem(data[i:], &flags)
- if flags&ListItemContainsBlock != 0 {
- block.ListData.Tight = false
- }
- i += skip
- if skip == 0 || flags&ListItemEndOfList != 0 {
- break
- }
- flags &= ^ListItemBeginningOfList
- }
-
- above := block.Parent
- finalizeList(block)
- p.tip = above
- return i
-}
-
-// Returns true if block ends with a blank line, descending if needed
-// into lists and sublists.
-func endsWithBlankLine(block *Node) bool {
- // TODO: figure this out. Always false now.
- for block != nil {
- //if block.lastLineBlank {
- //return true
- //}
- t := block.Type
- if t == List || t == Item {
- block = block.LastChild
- } else {
- break
- }
- }
- return false
-}
-
-func finalizeList(block *Node) {
- block.open = false
- item := block.FirstChild
- for item != nil {
- // check for non-final list item ending with blank line:
- if endsWithBlankLine(item) && item.Next != nil {
- block.ListData.Tight = false
- break
- }
- // recurse into children of list item, to see if there are spaces
- // between any of them:
- subItem := item.FirstChild
- for subItem != nil {
- if endsWithBlankLine(subItem) && (item.Next != nil || subItem.Next != nil) {
- block.ListData.Tight = false
- break
- }
- subItem = subItem.Next
- }
- item = item.Next
- }
-}
-
-// Parse a single list item.
-// Assumes initial prefix is already removed if this is a sublist.
-func (p *Markdown) listItem(data []byte, flags *ListType) int {
- // keep track of the indentation of the first line
- itemIndent := 0
- if data[0] == '\t' {
- itemIndent += 4
- } else {
- for itemIndent < 3 && data[itemIndent] == ' ' {
- itemIndent++
- }
- }
-
- var bulletChar byte = '*'
- i := p.uliPrefix(data)
- if i == 0 {
- i = p.oliPrefix(data)
- } else {
- bulletChar = data[i-2]
- }
- if i == 0 {
- i = p.dliPrefix(data)
- // reset definition term flag
- if i > 0 {
- *flags &= ^ListTypeTerm
- }
- }
- if i == 0 {
- // if in definition list, set term flag and continue
- if *flags&ListTypeDefinition != 0 {
- *flags |= ListTypeTerm
- } else {
- return 0
- }
- }
-
- // skip leading whitespace on first line
- for i < len(data) && data[i] == ' ' {
- i++
- }
-
- // find the end of the line
- line := i
- for i > 0 && i < len(data) && data[i-1] != '\n' {
- i++
- }
-
- // get working buffer
- var raw bytes.Buffer
-
- // put the first line into the working buffer
- raw.Write(data[line:i])
- line = i
-
- // process the following lines
- containsBlankLine := false
- sublist := 0
- lastChunkSize := 0
-
-gatherlines:
- for line < len(data) {
- i++
-
- // find the end of this line
- for i < len(data) && data[i-1] != '\n' {
- i++
- }
-
- // if it is an empty line, guess that it is part of this item
- // and move on to the next line
- if p.isEmpty(data[line:i]) > 0 {
- containsBlankLine = true
- line = i
- continue
- }
-
- // calculate the indentation
- indent := 0
- indentIndex := 0
- if data[line] == '\t' {
- indentIndex++
- indent += 4
- } else {
- for indent < 4 && line+indent < i && data[line+indent] == ' ' {
- indent++
- indentIndex++
- }
- }
-
- chunk := data[line+indentIndex : i]
-
- // evaluate how this line fits in
- switch {
- // is this a nested list item?
- case (p.uliPrefix(chunk) > 0 && !p.isHRule(chunk)) ||
- p.oliPrefix(chunk) > 0 ||
- p.dliPrefix(chunk) > 0:
-
- if containsBlankLine {
- *flags |= ListItemContainsBlock
- }
-
- // to be a nested list, it must be indented more
- // if not, it is the next item in the same list
- if indent <= itemIndent {
- break gatherlines
- }
-
- // is this the first item in the nested list?
- if sublist == 0 {
- if p.dliPrefix(chunk) > 0 {
- sublist = raw.Len() - lastChunkSize
- } else {
- sublist = raw.Len()
- }
- }
-
- // is this a nested prefix heading?
- case p.isPrefixHeading(chunk):
- // if the heading is not indented, it is not nested in the list
- // and thus ends the list
- if containsBlankLine && indent < 4 {
- *flags |= ListItemEndOfList
- break gatherlines
- }
- *flags |= ListItemContainsBlock
-
- // anything following an empty line is only part
- // of this item if it is indented 4 spaces
- // (regardless of the indentation of the beginning of the item)
- case containsBlankLine && indent < 4:
- if *flags&ListTypeDefinition != 0 && i < len(data)-1 {
- // is the next item still a part of this list?
- next := i
- for next < len(data) && data[next] != '\n' {
- next++
- }
- for next < len(data)-1 && data[next] == '\n' {
- next++
- }
- if i < len(data)-1 && data[i] != ':' && data[next] != ':' {
- *flags |= ListItemEndOfList
- }
- } else {
- *flags |= ListItemEndOfList
- }
- break gatherlines
-
- // a blank line means this should be parsed as a block
- case containsBlankLine:
- raw.WriteByte('\n')
- *flags |= ListItemContainsBlock
- }
-
- // if this line was preceded by one or more blanks,
- // re-introduce the blank into the buffer
- if containsBlankLine {
- containsBlankLine = false
- raw.WriteByte('\n')
- }
-
- // add the line into the working buffer without prefix
- raw.Write(data[line+indentIndex : i])
-
- // remember how much was written into raw, if this turns out to be a
- // definition list we'll need this number to know where the sublist starts
- lastChunkSize = i - (line + indentIndex)
-
- line = i
- }
-
- rawBytes := raw.Bytes()
-
- block := p.addBlock(Item, nil)
- block.ListFlags = *flags
- block.Tight = false
- block.BulletChar = bulletChar
- block.Delimiter = '.' // Only '.' is possible in Markdown, but ')' will also be possible in CommonMark
-
- // render the contents of the list item
- if *flags&ListItemContainsBlock != 0 && *flags&ListTypeTerm == 0 {
- // intermediate render of block item, except for definition term
- if sublist > 0 {
- p.block(rawBytes[:sublist])
- p.block(rawBytes[sublist:])
- } else {
- p.block(rawBytes)
- }
- } else {
- // intermediate render of inline item
- if sublist > 0 {
- child := p.addChild(Paragraph, 0)
- child.content = rawBytes[:sublist]
- p.block(rawBytes[sublist:])
- } else {
- child := p.addChild(Paragraph, 0)
- child.content = rawBytes
- }
- }
- return line
-}
-
-// render a single paragraph that has already been parsed out
-func (p *Markdown) renderParagraph(data []byte) {
- if len(data) == 0 {
- return
- }
-
- // trim leading spaces
- beg := 0
- for data[beg] == ' ' {
- beg++
- }
-
- end := len(data)
- // trim trailing newline
- if data[len(data)-1] == '\n' {
- end--
- }
-
- // trim trailing spaces
- for end > beg && data[end-1] == ' ' {
- end--
- }
-
- p.addBlock(Paragraph, data[beg:end])
-}
-
-func (p *Markdown) paragraph(data []byte) int {
- // prev: index of 1st char of previous line
- // line: index of 1st char of current line
- // i: index of cursor/end of current line
- var prev, line, i int
- tabSize := TabSizeDefault
- if p.extensions&TabSizeEight != 0 {
- tabSize = TabSizeDouble
- }
- // keep going until we find something to mark the end of the paragraph
- for i < len(data) {
- // mark the beginning of the current line
- prev = line
- current := data[i:]
- line = i
-
- // did we find a reference or a footnote? If so, end a paragraph
- // preceding it and report that we have consumed up to the end of that
- // reference:
- if refEnd := isReference(p, current, tabSize); refEnd > 0 {
- p.renderParagraph(data[:i])
- return i + refEnd
- }
-
- // did we find a blank line marking the end of the paragraph?
- if n := p.isEmpty(current); n > 0 {
- // did this blank line followed by a definition list item?
- if p.extensions&DefinitionLists != 0 {
- if i < len(data)-1 && data[i+1] == ':' {
- return p.list(data[prev:], ListTypeDefinition)
- }
- }
-
- p.renderParagraph(data[:i])
- return i + n
- }
-
- // an underline under some text marks a heading, so our paragraph ended on prev line
- if i > 0 {
- if level := p.isUnderlinedHeading(current); level > 0 {
- // render the paragraph
- p.renderParagraph(data[:prev])
-
- // ignore leading and trailing whitespace
- eol := i - 1
- for prev < eol && data[prev] == ' ' {
- prev++
- }
- for eol > prev && data[eol-1] == ' ' {
- eol--
- }
-
- id := ""
- if p.extensions&AutoHeadingIDs != 0 {
- id = sanitized_anchor_name.Create(string(data[prev:eol]))
- }
-
- block := p.addBlock(Heading, data[prev:eol])
- block.Level = level
- block.HeadingID = id
-
- // find the end of the underline
- for i < len(data) && data[i] != '\n' {
- i++
- }
- return i
- }
- }
-
- // if the next line starts a block of HTML, then the paragraph ends here
- if p.extensions&LaxHTMLBlocks != 0 {
- if data[i] == '<' && p.html(current, false) > 0 {
- // rewind to before the HTML block
- p.renderParagraph(data[:i])
- return i
- }
- }
-
- // if there's a prefixed heading or a horizontal rule after this, paragraph is over
- if p.isPrefixHeading(current) || p.isHRule(current) {
- p.renderParagraph(data[:i])
- return i
- }
-
- // if there's a fenced code block, paragraph is over
- if p.extensions&FencedCode != 0 {
- if p.fencedCodeBlock(current, false) > 0 {
- p.renderParagraph(data[:i])
- return i
- }
- }
-
- // if there's a definition list item, prev line is a definition term
- if p.extensions&DefinitionLists != 0 {
- if p.dliPrefix(current) != 0 {
- ret := p.list(data[prev:], ListTypeDefinition)
- return ret
- }
- }
-
- // if there's a list after this, paragraph is over
- if p.extensions&NoEmptyLineBeforeBlock != 0 {
- if p.uliPrefix(current) != 0 ||
- p.oliPrefix(current) != 0 ||
- p.quotePrefix(current) != 0 ||
- p.codePrefix(current) != 0 {
- p.renderParagraph(data[:i])
- return i
- }
- }
-
- // otherwise, scan to the beginning of the next line
- nl := bytes.IndexByte(data[i:], '\n')
- if nl >= 0 {
- i += nl + 1
- } else {
- i += len(data[i:])
- }
- }
-
- p.renderParagraph(data[:i])
- return i
-}
-
-func skipChar(data []byte, start int, char byte) int {
- i := start
- for i < len(data) && data[i] == char {
- i++
- }
- return i
-}
-
-func skipUntilChar(text []byte, start int, char byte) int {
- i := start
- for i < len(text) && text[i] != char {
- i++
- }
- return i
-}
diff --git a/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/doc.go b/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/doc.go
deleted file mode 100644
index 5b3fa98..0000000
--- a/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/doc.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Package blackfriday is a markdown processor.
-//
-// It translates plain text with simple formatting rules into an AST, which can
-// then be further processed to HTML (provided by Blackfriday itself) or other
-// formats (provided by the community).
-//
-// The simplest way to invoke Blackfriday is to call the Run function. It will
-// take a text input and produce a text output in HTML (or other format).
-//
-// A slightly more sophisticated way to use Blackfriday is to create a Markdown
-// processor and to call Parse, which returns a syntax tree for the input
-// document. You can leverage Blackfriday's parsing for content extraction from
-// markdown documents. You can assign a custom renderer and set various options
-// to the Markdown processor.
-//
-// If you're interested in calling Blackfriday from command line, see
-// https://github.com/russross/blackfriday-tool.
-package blackfriday
diff --git a/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/esc.go b/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/esc.go
deleted file mode 100644
index 6385f27..0000000
--- a/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/esc.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package blackfriday
-
-import (
- "html"
- "io"
-)
-
-var htmlEscaper = [256][]byte{
- '&': []byte("&amp;"),
- '<': []byte("&lt;"),
- '>': []byte("&gt;"),
- '"': []byte("&quot;"),
-}
-
-func escapeHTML(w io.Writer, s []byte) {
- var start, end int
- for end < len(s) {
- escSeq := htmlEscaper[s[end]]
- if escSeq != nil {
- w.Write(s[start:end])
- w.Write(escSeq)
- start = end + 1
- }
- end++
- }
- if start < len(s) && end <= len(s) {
- w.Write(s[start:end])
- }
-}
-
-func escLink(w io.Writer, text []byte) {
- unesc := html.UnescapeString(string(text))
- escapeHTML(w, []byte(unesc))
-}
diff --git a/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/html.go b/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/html.go
deleted file mode 100644
index 9fbf820..0000000
--- a/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/html.go
+++ /dev/null
@@ -1,941 +0,0 @@
-//
-// Blackfriday Markdown Processor
-// Available at http://github.com/russross/blackfriday
-//
-// Copyright © 2011 Russ Ross <russ@russross.com>.
-// Distributed under the Simplified BSD License.
-// See README.md for details.
-//
-
-//
-//
-// HTML rendering backend
-//
-//
-
-//nolint:gocritic,unused,revive // ignore blackfriday
-package blackfriday
-
-import (
- "bytes"
- "fmt"
- "io"
- "regexp"
- "strings"
-)
-
-// HTMLFlags control optional behavior of HTML renderer.
-type HTMLFlags int
-
-// HTML renderer configuration options.
-const (
- HTMLFlagsNone HTMLFlags = 0
- SkipHTML HTMLFlags = 1 << iota // Skip preformatted HTML blocks
- SkipImages // Skip embedded images
- SkipLinks // Skip all links
- Safelink // Only link to trusted protocols
- NofollowLinks // Only link with rel="nofollow"
- NoreferrerLinks // Only link with rel="noreferrer"
- HrefTargetBlank // Add a blank target
- CompletePage // Generate a complete HTML page
- UseXHTML // Generate XHTML output instead of HTML
- FootnoteReturnLinks // Generate a link at the end of a footnote to return to the source
- Smartypants // Enable smart punctuation substitutions
- SmartypantsFractions // Enable smart fractions (with Smartypants)
- SmartypantsDashes // Enable smart dashes (with Smartypants)
- SmartypantsLatexDashes // Enable LaTeX-style dashes (with Smartypants)
- SmartypantsAngledQuotes // Enable angled double quotes (with Smartypants) for double quotes rendering
- SmartypantsQuotesNBSP // Enable « French guillemets » (with Smartypants)
- TOC // Generate a table of contents
-)
-
-var (
- htmlTagRe = regexp.MustCompile("(?i)^" + htmlTag)
-)
-
-const (
- htmlTag = "(?:" + openTag + "|" + closeTag + "|" + htmlComment + "|" +
- processingInstruction + "|" + declaration + "|" + cdata + ")"
- closeTag = "</" + tagName + "\\s*[>]"
- openTag = "<" + tagName + attribute + "*" + "\\s*/?>"
- attribute = "(?:" + "\\s+" + attributeName + attributeValueSpec + "?)"
- attributeValue = "(?:" + unquotedValue + "|" + singleQuotedValue + "|" + doubleQuotedValue + ")"
- attributeValueSpec = "(?:" + "\\s*=" + "\\s*" + attributeValue + ")"
- attributeName = "[a-zA-Z_:][a-zA-Z0-9:._-]*"
- cdata = "<!\\[CDATA\\[[\\s\\S]*?\\]\\]>"
- declaration = "<![A-Z]+" + "\\s+[^>]*>"
- doubleQuotedValue = "\"[^\"]*\""
- htmlComment = "<!---->|<!--(?:-?[^>-])(?:-?[^-])*-->"
- processingInstruction = "[<][?].*?[?][>]"
- singleQuotedValue = "'[^']*'"
- tagName = "[A-Za-z][A-Za-z0-9-]*"
- unquotedValue = "[^\"'=<>`\\x00-\\x20]+"
-)
-
-// HTMLRendererParameters is a collection of supplementary parameters tweaking
-// the behavior of various parts of HTML renderer.
-type HTMLRendererParameters struct {
- // Prepend this text to each relative URL.
- AbsolutePrefix string
- // Add this text to each footnote anchor, to ensure uniqueness.
- FootnoteAnchorPrefix string
- // Show this text inside the <a> tag for a footnote return link, if the
- // HTML_FOOTNOTE_RETURN_LINKS flag is enabled. If blank, the string
- // <sup>[return]</sup> is used.
- FootnoteReturnLinkContents string
- // If set, add this text to the front of each Heading ID, to ensure
- // uniqueness.
- HeadingIDPrefix string
- // If set, add this text to the back of each Heading ID, to ensure uniqueness.
- HeadingIDSuffix string
-
- Title string // Document title (used if CompletePage is set)
- CSS string // Optional CSS file URL (used if CompletePage is set)
- Icon string // Optional icon file URL (used if CompletePage is set)
-
- Flags HTMLFlags // Flags allow customizing this renderer's behavior
-}
-
-// HTMLRenderer is a type that implements the Renderer interface for HTML output.
-//
-// Do not create this directly, instead use the NewHTMLRenderer function.
-type HTMLRenderer struct {
- HTMLRendererParameters
-
- closeTag string // how to end singleton tags: either " />" or ">"
-
- // Track heading IDs to prevent ID collision in a single generation.
- headingIDs map[string]int
-
- lastOutputLen int
- disableTags int
-
- sr *SPRenderer
-}
-
-const (
- xhtmlClose = " />"
- htmlClose = ">"
-)
-
-// NewHTMLRenderer creates and configures an HTMLRenderer object, which
-// satisfies the Renderer interface.
-func NewHTMLRenderer(params HTMLRendererParameters) *HTMLRenderer {
- // configure the rendering engine
- closeTag := htmlClose
- if params.Flags&UseXHTML != 0 {
- closeTag = xhtmlClose
- }
-
- if params.FootnoteReturnLinkContents == "" {
- params.FootnoteReturnLinkContents = `<sup>[return]</sup>`
- }
-
- return &HTMLRenderer{
- HTMLRendererParameters: params,
-
- closeTag: closeTag,
- headingIDs: make(map[string]int),
-
- sr: NewSmartypantsRenderer(params.Flags),
- }
-}
-
-func isHTMLTag(tag []byte, tagname string) bool {
- found, _ := findHTMLTagPos(tag, tagname)
- return found
-}
-
-// Look for a character, but ignore it when it's in any kind of quotes, it
-// might be JavaScript
-func skipUntilCharIgnoreQuotes(html []byte, start int, char byte) int {
- inSingleQuote := false
- inDoubleQuote := false
- inGraveQuote := false
- i := start
- for i < len(html) {
- switch {
- case html[i] == char && !inSingleQuote && !inDoubleQuote && !inGraveQuote:
- return i
- case html[i] == '\'':
- inSingleQuote = !inSingleQuote
- case html[i] == '"':
- inDoubleQuote = !inDoubleQuote
- case html[i] == '`':
- inGraveQuote = !inGraveQuote
- }
- i++
- }
- return start
-}
-
-func findHTMLTagPos(tag []byte, tagname string) (bool, int) {
- i := 0
- if i < len(tag) && tag[0] != '<' {
- return false, -1
- }
- i++
- i = skipSpace(tag, i)
-
- if i < len(tag) && tag[i] == '/' {
- i++
- }
-
- i = skipSpace(tag, i)
- j := 0
- for ; i < len(tag); i, j = i+1, j+1 {
- if j >= len(tagname) {
- break
- }
-
- if strings.ToLower(string(tag[i]))[0] != tagname[j] {
- return false, -1
- }
- }
-
- if i == len(tag) {
- return false, -1
- }
-
- rightAngle := skipUntilCharIgnoreQuotes(tag, i, '>')
- if rightAngle >= i {
- return true, rightAngle
- }
-
- return false, -1
-}
-
-func skipSpace(tag []byte, i int) int {
- for i < len(tag) && isspace(tag[i]) {
- i++
- }
- return i
-}
-
-func isRelativeLink(link []byte) (yes bool) {
- // a tag begin with '#'
- if link[0] == '#' {
- return true
- }
-
- // link begin with '/' but not '//', the second maybe a protocol relative link
- if len(link) >= 2 && link[0] == '/' && link[1] != '/' {
- return true
- }
-
- // only the root '/'
- if len(link) == 1 && link[0] == '/' {
- return true
- }
-
- // current directory : begin with "./"
- if bytes.HasPrefix(link, []byte("./")) {
- return true
- }
-
- // parent directory : begin with "../"
- if bytes.HasPrefix(link, []byte("../")) {
- return true
- }
-
- return false
-}
-
-func (r *HTMLRenderer) ensureUniqueHeadingID(id string) string {
- for count, found := r.headingIDs[id]; found; count, found = r.headingIDs[id] {
- tmp := fmt.Sprintf("%s-%d", id, count+1)
-
- if _, tmpFound := r.headingIDs[tmp]; !tmpFound {
- r.headingIDs[id] = count + 1
- id = tmp
- } else {
- id = id + "-1"
- }
- }
-
- if _, found := r.headingIDs[id]; !found {
- r.headingIDs[id] = 0
- }
-
- return id
-}
-
-func (r *HTMLRenderer) addAbsPrefix(link []byte) []byte {
- if r.AbsolutePrefix != "" && isRelativeLink(link) && link[0] != '.' {
- newDest := r.AbsolutePrefix
- if link[0] != '/' {
- newDest += "/"
- }
- newDest += string(link)
- return []byte(newDest)
- }
- return link
-}
-
-func appendLinkAttrs(attrs []string, flags HTMLFlags, link []byte) []string {
- if isRelativeLink(link) {
- return attrs
- }
- val := []string{}
- if flags&NofollowLinks != 0 {
- val = append(val, "nofollow")
- }
- if flags&NoreferrerLinks != 0 {
- val = append(val, "noreferrer")
- }
- if flags&HrefTargetBlank != 0 {
- attrs = append(attrs, "target=\"_blank\"")
- }
- if len(val) == 0 {
- return attrs
- }
- attr := fmt.Sprintf("rel=%q", strings.Join(val, " "))
- return append(attrs, attr)
-}
-
-func isMailto(link []byte) bool {
- return bytes.HasPrefix(link, []byte("mailto:"))
-}
-
-func needSkipLink(flags HTMLFlags, dest []byte) bool {
- if flags&SkipLinks != 0 {
- return true
- }
- return flags&Safelink != 0 && !isSafeLink(dest) && !isMailto(dest)
-}
-
-func isSmartypantable(node *Node) bool {
- pt := node.Parent.Type
- return pt != Link && pt != CodeBlock && pt != Code
-}
-
-func appendLanguageAttr(attrs []string, info []byte) []string {
- if len(info) == 0 {
- return attrs
- }
- endOfLang := bytes.IndexAny(info, "\t ")
- if endOfLang < 0 {
- endOfLang = len(info)
- }
- return append(attrs, fmt.Sprintf("class=\"language-%s\"", info[:endOfLang]))
-}
-
-func (r *HTMLRenderer) tag(w io.Writer, name []byte, attrs []string) {
- w.Write(name)
- if len(attrs) > 0 {
- w.Write(spaceBytes)
- w.Write([]byte(strings.Join(attrs, " ")))
- }
- w.Write(gtBytes)
- r.lastOutputLen = 1
-}
-
-func footnoteRef(prefix string, node *Node) []byte {
- urlFrag := prefix + string(slugify(node.Destination))
- anchor := fmt.Sprintf(`<a rel="footnote" href="#fn:%s">%d</a>`, urlFrag, node.NoteID)
- return []byte(fmt.Sprintf(`<sup class="footnote-ref" id="fnref:%s">%s</sup>`, urlFrag, anchor))
-}
-
-func footnoteItem(prefix string, slug []byte) []byte {
- return []byte(fmt.Sprintf(`<li id="fn:%s%s">`, prefix, slug))
-}
-
-func footnoteReturnLink(prefix, returnLink string, slug []byte) []byte {
- const format = ` <a class="footnote-return" href="#fnref:%s%s">%s</a>`
- return []byte(fmt.Sprintf(format, prefix, slug, returnLink))
-}
-
-func itemOpenCR(node *Node) bool {
- if node.Prev == nil {
- return false
- }
- ld := node.Parent.ListData
- return !ld.Tight && ld.ListFlags&ListTypeDefinition == 0
-}
-
-func skipParagraphTags(node *Node) bool {
- grandparent := node.Parent.Parent
- if grandparent == nil || grandparent.Type != List {
- return false
- }
- tightOrTerm := grandparent.Tight || node.Parent.ListFlags&ListTypeTerm != 0
- return grandparent.Type == List && tightOrTerm
-}
-
-func cellAlignment(align CellAlignFlags) string {
- switch align {
- case TableAlignmentLeft:
- return "left"
- case TableAlignmentRight:
- return "right"
- case TableAlignmentCenter:
- return "center"
- default:
- return ""
- }
-}
-
-func (r *HTMLRenderer) out(w io.Writer, text []byte) {
- if r.disableTags > 0 {
- w.Write(htmlTagRe.ReplaceAll(text, []byte{}))
- } else {
- w.Write(text)
- }
- r.lastOutputLen = len(text)
-}
-
-func (r *HTMLRenderer) cr(w io.Writer) {
- if r.lastOutputLen > 0 {
- r.out(w, nlBytes)
- }
-}
-
-var (
- nlBytes = []byte{'\n'}
- gtBytes = []byte{'>'}
- spaceBytes = []byte{' '}
-)
-
-var (
- brTag = []byte("<br>")
- brXHTMLTag = []byte("<br />")
- emTag = []byte("<em>")
- emCloseTag = []byte("</em>")
- strongTag = []byte("<strong>")
- strongCloseTag = []byte("</strong>")
- delTag = []byte("<del>")
- delCloseTag = []byte("</del>")
- ttTag = []byte("<tt>")
- ttCloseTag = []byte("</tt>")
- aTag = []byte("<a")
- aCloseTag = []byte("</a>")
- preTag = []byte("<pre>")
- preCloseTag = []byte("</pre>")
- codeTag = []byte("<code>")
- codeCloseTag = []byte("</code>")
- pTag = []byte("<p>")
- pCloseTag = []byte("</p>")
- blockquoteTag = []byte("<blockquote>")
- blockquoteCloseTag = []byte("</blockquote>")
- hrTag = []byte("<hr>")
- hrXHTMLTag = []byte("<hr />")
- ulTag = []byte("<ul>")
- ulCloseTag = []byte("</ul>")
- olTag = []byte("<ol>")
- olCloseTag = []byte("</ol>")
- dlTag = []byte("<dl>")
- dlCloseTag = []byte("</dl>")
- liTag = []byte("<li>")
- liCloseTag = []byte("</li>")
- ddTag = []byte("<dd>")
- ddCloseTag = []byte("</dd>")
- dtTag = []byte("<dt>")
- dtCloseTag = []byte("</dt>")
- tableTag = []byte("<table>")
- tableCloseTag = []byte("</table>")
- tdTag = []byte("<td")
- tdCloseTag = []byte("</td>")
- thTag = []byte("<th")
- thCloseTag = []byte("</th>")
- theadTag = []byte("<thead>")
- theadCloseTag = []byte("</thead>")
- tbodyTag = []byte("<tbody>")
- tbodyCloseTag = []byte("</tbody>")
- trTag = []byte("<tr>")
- trCloseTag = []byte("</tr>")
- h1Tag = []byte("<h1")
- h1CloseTag = []byte("</h1>")
- h2Tag = []byte("<h2")
- h2CloseTag = []byte("</h2>")
- h3Tag = []byte("<h3")
- h3CloseTag = []byte("</h3>")
- h4Tag = []byte("<h4")
- h4CloseTag = []byte("</h4>")
- h5Tag = []byte("<h5")
- h5CloseTag = []byte("</h5>")
- h6Tag = []byte("<h6")
- h6CloseTag = []byte("</h6>")
-
- footnotesDivBytes = []byte("\n<div class=\"footnotes\">\n\n")
- footnotesCloseDivBytes = []byte("\n</div>\n")
-)
-
-func headingTagsFromLevel(level int) ([]byte, []byte) {
- switch level {
- case 1:
- return h1Tag, h1CloseTag
- case 2:
- return h2Tag, h2CloseTag
- case 3:
- return h3Tag, h3CloseTag
- case 4:
- return h4Tag, h4CloseTag
- case 5:
- return h5Tag, h5CloseTag
- default:
- return h6Tag, h6CloseTag
- }
-}
-
-func (r *HTMLRenderer) outHRTag(w io.Writer) {
- if r.Flags&UseXHTML == 0 {
- r.out(w, hrTag)
- } else {
- r.out(w, hrXHTMLTag)
- }
-}
-
-// RenderNode is a default renderer of a single node of a syntax tree. For
-// block nodes it will be called twice: first time with entering=true, second
-// time with entering=false, so that it could know when it's working on an open
-// tag and when on close. It writes the result to w.
-//
-// The return value is a way to tell the calling walker to adjust its walk
-// pattern: e.g. it can terminate the traversal by returning Terminate. Or it
-// can ask the walker to skip a subtree of this node by returning SkipChildren.
-// The typical behavior is to return GoToNext, which asks for the usual
-// traversal to the next node.
-func (r *HTMLRenderer) RenderNode(w io.Writer, node *Node, entering bool) WalkStatus {
- attrs := []string{}
- switch node.Type {
- case Text:
- if r.Flags&Smartypants != 0 {
- var tmp bytes.Buffer
- escapeHTML(&tmp, node.Literal)
- r.sr.Process(w, tmp.Bytes())
- } else {
- if node.Parent.Type == Link {
- escLink(w, node.Literal)
- } else {
- escapeHTML(w, node.Literal)
- }
- }
- case Softbreak:
- r.cr(w)
- // TODO: make it configurable via out(renderer.softbreak)
- case Hardbreak:
- if r.Flags&UseXHTML == 0 {
- r.out(w, brTag)
- } else {
- r.out(w, brXHTMLTag)
- }
- r.cr(w)
- case Emph:
- if entering {
- r.out(w, emTag)
- } else {
- r.out(w, emCloseTag)
- }
- case Strong:
- if entering {
- r.out(w, strongTag)
- } else {
- r.out(w, strongCloseTag)
- }
- case Del:
- if entering {
- r.out(w, delTag)
- } else {
- r.out(w, delCloseTag)
- }
- case HTMLSpan:
- if r.Flags&SkipHTML != 0 {
- break
- }
- r.out(w, node.Literal)
- case Link:
- // mark it but don't link it if it is not a safe link: no smartypants
- dest := node.LinkData.Destination
- if needSkipLink(r.Flags, dest) {
- if entering {
- r.out(w, ttTag)
- } else {
- r.out(w, ttCloseTag)
- }
- } else {
- if entering {
- dest = r.addAbsPrefix(dest)
- var hrefBuf bytes.Buffer
- hrefBuf.WriteString("href=\"")
- escLink(&hrefBuf, dest)
- hrefBuf.WriteByte('"')
- attrs = append(attrs, hrefBuf.String())
- if node.NoteID != 0 {
- r.out(w, footnoteRef(r.FootnoteAnchorPrefix, node))
- break
- }
- attrs = appendLinkAttrs(attrs, r.Flags, dest)
- if len(node.LinkData.Title) > 0 {
- var titleBuff bytes.Buffer
- titleBuff.WriteString("title=\"")
- escapeHTML(&titleBuff, node.LinkData.Title)
- titleBuff.WriteByte('"')
- attrs = append(attrs, titleBuff.String())
- }
- r.tag(w, aTag, attrs)
- } else {
- if node.NoteID != 0 {
- break
- }
- r.out(w, aCloseTag)
- }
- }
- case Image:
- if r.Flags&SkipImages != 0 {
- return SkipChildren
- }
- if entering {
- dest := node.LinkData.Destination
- dest = r.addAbsPrefix(dest)
- if r.disableTags == 0 {
- //if options.safe && potentiallyUnsafe(dest) {
- //out(w, `<img src="" alt="`)
- //} else {
- r.out(w, []byte(`<img src="`))
- escLink(w, dest)
- r.out(w, []byte(`" alt="`))
- //}
- }
- r.disableTags++
- } else {
- r.disableTags--
- if r.disableTags == 0 {
- if node.LinkData.Title != nil {
- r.out(w, []byte(`" title="`))
- escapeHTML(w, node.LinkData.Title)
- }
- r.out(w, []byte(`" />`))
- }
- }
- case Code:
- r.out(w, codeTag)
- escapeHTML(w, node.Literal)
- r.out(w, codeCloseTag)
- case Document:
- break
- case Paragraph:
- if skipParagraphTags(node) {
- break
- }
- if entering {
- // TODO: untangle this clusterfuck about when the newlines need
- // to be added and when not.
- if node.Prev != nil {
- switch node.Prev.Type {
- case HTMLBlock, List, Paragraph, Heading, CodeBlock, BlockQuote, HorizontalRule:
- r.cr(w)
- }
- }
- if node.Parent.Type == BlockQuote && node.Prev == nil {
- r.cr(w)
- }
- r.out(w, pTag)
- } else {
- r.out(w, pCloseTag)
- if !(node.Parent.Type == Item && node.Next == nil) {
- r.cr(w)
- }
- }
- case BlockQuote:
- if entering {
- r.cr(w)
- r.out(w, blockquoteTag)
- } else {
- r.out(w, blockquoteCloseTag)
- r.cr(w)
- }
- case HTMLBlock:
- if r.Flags&SkipHTML != 0 {
- break
- }
- r.cr(w)
- r.out(w, node.Literal)
- r.cr(w)
- case Heading:
- openTag, closeTag := headingTagsFromLevel(node.Level)
- if entering {
- if node.IsTitleblock {
- attrs = append(attrs, `class="title"`)
- }
- if node.HeadingID != "" {
- id := r.ensureUniqueHeadingID(node.HeadingID)
- if r.HeadingIDPrefix != "" {
- id = r.HeadingIDPrefix + id
- }
- if r.HeadingIDSuffix != "" {
- id = id + r.HeadingIDSuffix
- }
- attrs = append(attrs, fmt.Sprintf(`id="%s"`, id))
- }
- r.cr(w)
- r.tag(w, openTag, attrs)
- } else {
- r.out(w, closeTag)
- if !(node.Parent.Type == Item && node.Next == nil) {
- r.cr(w)
- }
- }
- case HorizontalRule:
- r.cr(w)
- r.outHRTag(w)
- r.cr(w)
- case List:
- openTag := ulTag
- closeTag := ulCloseTag
- if node.ListFlags&ListTypeOrdered != 0 {
- openTag = olTag
- closeTag = olCloseTag
- }
- if node.ListFlags&ListTypeDefinition != 0 {
- openTag = dlTag
- closeTag = dlCloseTag
- }
- if entering {
- if node.IsFootnotesList {
- r.out(w, footnotesDivBytes)
- r.outHRTag(w)
- r.cr(w)
- }
- r.cr(w)
- if node.Parent.Type == Item && node.Parent.Parent.Tight {
- r.cr(w)
- }
- r.tag(w, openTag[:len(openTag)-1], attrs)
- r.cr(w)
- } else {
- r.out(w, closeTag)
- //cr(w)
- //if node.parent.Type != Item {
- // cr(w)
- //}
- if node.Parent.Type == Item && node.Next != nil {
- r.cr(w)
- }
- if node.Parent.Type == Document || node.Parent.Type == BlockQuote {
- r.cr(w)
- }
- if node.IsFootnotesList {
- r.out(w, footnotesCloseDivBytes)
- }
- }
- case Item:
- openTag := liTag
- closeTag := liCloseTag
- if node.ListFlags&ListTypeDefinition != 0 {
- openTag = ddTag
- closeTag = ddCloseTag
- }
- if node.ListFlags&ListTypeTerm != 0 {
- openTag = dtTag
- closeTag = dtCloseTag
- }
- if entering {
- if itemOpenCR(node) {
- r.cr(w)
- }
- if node.ListData.RefLink != nil {
- slug := slugify(node.ListData.RefLink)
- r.out(w, footnoteItem(r.FootnoteAnchorPrefix, slug))
- break
- }
- r.out(w, openTag)
- } else {
- if node.ListData.RefLink != nil {
- slug := slugify(node.ListData.RefLink)
- if r.Flags&FootnoteReturnLinks != 0 {
- r.out(w, footnoteReturnLink(r.FootnoteAnchorPrefix, r.FootnoteReturnLinkContents, slug))
- }
- }
- r.out(w, closeTag)
- r.cr(w)
- }
- case CodeBlock:
- attrs = appendLanguageAttr(attrs, node.Info)
- r.cr(w)
- r.out(w, preTag)
- r.tag(w, codeTag[:len(codeTag)-1], attrs)
- escapeHTML(w, node.Literal)
- r.out(w, codeCloseTag)
- r.out(w, preCloseTag)
- if node.Parent.Type != Item {
- r.cr(w)
- }
- case Table:
- if entering {
- r.cr(w)
- r.out(w, tableTag)
- } else {
- r.out(w, tableCloseTag)
- r.cr(w)
- }
- case TableCell:
- openTag := tdTag
- closeTag := tdCloseTag
- if node.IsHeader {
- openTag = thTag
- closeTag = thCloseTag
- }
- if entering {
- align := cellAlignment(node.Align)
- if align != "" {
- attrs = append(attrs, fmt.Sprintf(`align="%s"`, align))
- }
- if node.Prev == nil {
- r.cr(w)
- }
- r.tag(w, openTag, attrs)
- } else {
- r.out(w, closeTag)
- r.cr(w)
- }
- case TableHead:
- if entering {
- r.cr(w)
- r.out(w, theadTag)
- } else {
- r.out(w, theadCloseTag)
- r.cr(w)
- }
- case TableBody:
- if entering {
- r.cr(w)
- r.out(w, tbodyTag)
- // XXX: this is to adhere to a rather silly test. Should fix test.
- if node.FirstChild == nil {
- r.cr(w)
- }
- } else {
- r.out(w, tbodyCloseTag)
- r.cr(w)
- }
- case TableRow:
- if entering {
- r.cr(w)
- r.out(w, trTag)
- } else {
- r.out(w, trCloseTag)
- r.cr(w)
- }
- default:
- panic("Unknown node type " + node.Type.String())
- }
- return GoToNext
-}
-
-// RenderHeader writes HTML document preamble and TOC if requested.
-func (r *HTMLRenderer) RenderHeader(w io.Writer, ast *Node) {
- r.writeDocumentHeader(w)
- if r.Flags&TOC != 0 {
- r.writeTOC(w, ast)
- }
-}
-
-// RenderFooter writes HTML document footer.
-func (r *HTMLRenderer) RenderFooter(w io.Writer, ast *Node) {
- if r.Flags&CompletePage == 0 {
- return
- }
- io.WriteString(w, "\n</body>\n</html>\n")
-}
-
-func (r *HTMLRenderer) writeDocumentHeader(w io.Writer) {
- if r.Flags&CompletePage == 0 {
- return
- }
- ending := ""
- if r.Flags&UseXHTML != 0 {
- io.WriteString(w, "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" ")
- io.WriteString(w, "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n")
- io.WriteString(w, "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n")
- ending = " /"
- } else {
- io.WriteString(w, "<!DOCTYPE html>\n")
- io.WriteString(w, "<html>\n")
- }
- io.WriteString(w, "<head>\n")
- io.WriteString(w, " <title>")
- if r.Flags&Smartypants != 0 {
- r.sr.Process(w, []byte(r.Title))
- } else {
- escapeHTML(w, []byte(r.Title))
- }
- io.WriteString(w, "</title>\n")
- io.WriteString(w, " <meta name=\"GENERATOR\" content=\"Blackfriday Markdown Processor v")
- io.WriteString(w, Version)
- io.WriteString(w, "\"")
- io.WriteString(w, ending)
- io.WriteString(w, ">\n")
- io.WriteString(w, " <meta charset=\"utf-8\"")
- io.WriteString(w, ending)
- io.WriteString(w, ">\n")
- if r.CSS != "" {
- io.WriteString(w, " <link rel=\"stylesheet\" type=\"text/css\" href=\"")
- escapeHTML(w, []byte(r.CSS))
- io.WriteString(w, "\"")
- io.WriteString(w, ending)
- io.WriteString(w, ">\n")
- }
- if r.Icon != "" {
- io.WriteString(w, " <link rel=\"icon\" type=\"image/x-icon\" href=\"")
- escapeHTML(w, []byte(r.Icon))
- io.WriteString(w, "\"")
- io.WriteString(w, ending)
- io.WriteString(w, ">\n")
- }
- io.WriteString(w, "</head>\n")
- io.WriteString(w, "<body>\n\n")
-}
-
-func (r *HTMLRenderer) writeTOC(w io.Writer, ast *Node) {
- buf := bytes.Buffer{}
-
- inHeading := false
- tocLevel := 0
- headingCount := 0
-
- ast.Walk(func(node *Node, entering bool) WalkStatus {
- if node.Type == Heading && !node.HeadingData.IsTitleblock {
- inHeading = entering
- if entering {
- node.HeadingID = fmt.Sprintf("toc_%d", headingCount)
- if node.Level == tocLevel {
- buf.WriteString("</li>\n\n<li>")
- } else if node.Level < tocLevel {
- for node.Level < tocLevel {
- tocLevel--
- buf.WriteString("</li>\n</ul>")
- }
- buf.WriteString("</li>\n\n<li>")
- } else {
- for node.Level > tocLevel {
- tocLevel++
- buf.WriteString("\n<ul>\n<li>")
- }
- }
-
- fmt.Fprintf(&buf, `<a href="#toc_%d">`, headingCount)
- headingCount++
- } else {
- buf.WriteString("</a>")
- }
- return GoToNext
- }
-
- if inHeading {
- return r.RenderNode(&buf, node, entering)
- }
-
- return GoToNext
- })
-
- for ; tocLevel > 0; tocLevel-- {
- buf.WriteString("</li>\n</ul>")
- }
-
- if buf.Len() > 0 {
- io.WriteString(w, "<nav>\n")
- w.Write(buf.Bytes())
- io.WriteString(w, "\n\n</nav>\n")
- }
- r.lastOutputLen = buf.Len()
-}
diff --git a/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/inline.go b/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/inline.go
deleted file mode 100644
index 70557d5..0000000
--- a/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/inline.go
+++ /dev/null
@@ -1,1217 +0,0 @@
-//
-// Blackfriday Markdown Processor
-// Available at http://github.com/russross/blackfriday
-//
-// Copyright © 2011 Russ Ross <russ@russross.com>.
-// Distributed under the Simplified BSD License.
-// See README.md for details.
-//
-
-//
-// Functions to parse inline elements.
-//
-
-//nolint:gocritic,whitespace,wastedassign,revive // ignore blackfriday
-package blackfriday
-
-import (
- "bytes"
- "regexp"
- "strconv"
-)
-
-var (
- urlRe = `((https?|ftp):\/\/|\/)[-A-Za-z0-9+&@#\/%?=~_|!:,.;\(\)]+`
- anchorRe = regexp.MustCompile(`^(<a\shref="` + urlRe + `"(\stitle="[^"<>]+")?\s?>` + urlRe + `<\/a>)`)
-
- // TODO: improve this regexp to catch all possible entities:
- htmlEntityRe = regexp.MustCompile(`&[a-z]{2,5};`)
-)
-
-// Functions to parse text within a block
-// Each function returns the number of chars taken care of
-// data is the complete block being rendered
-// offset is the number of valid chars before the current cursor
-
-func (p *Markdown) inline(currBlock *Node, data []byte) {
- // handlers might call us recursively: enforce a maximum depth
- if p.nesting >= p.maxNesting || len(data) == 0 {
- return
- }
- p.nesting++
- beg, end := 0, 0
- for end < len(data) {
- handler := p.inlineCallback[data[end]]
- if handler != nil {
- if consumed, node := handler(p, data, end); consumed == 0 {
- // No action from the callback.
- end++
- } else {
- // Copy inactive chars into the output.
- currBlock.AppendChild(text(data[beg:end]))
- if node != nil {
- currBlock.AppendChild(node)
- }
- // Skip past whatever the callback used.
- beg = end + consumed
- end = beg
- }
- } else {
- end++
- }
- }
- if beg < len(data) {
- if data[end-1] == '\n' {
- end--
- }
- currBlock.AppendChild(text(data[beg:end]))
- }
- p.nesting--
-}
-
-// single and double emphasis parsing
-func emphasis(p *Markdown, data []byte, offset int) (int, *Node) {
- data = data[offset:]
- c := data[0]
-
- if len(data) > 2 && data[1] != c {
- // whitespace cannot follow an opening emphasis;
- // strikethrough only takes two characters '~~'
- if c == '~' || isspace(data[1]) {
- return 0, nil
- }
- ret, node := helperEmphasis(p, data[1:], c)
- if ret == 0 {
- return 0, nil
- }
-
- return ret + 1, node
- }
-
- if len(data) > 3 && data[1] == c && data[2] != c {
- if isspace(data[2]) {
- return 0, nil
- }
- ret, node := helperDoubleEmphasis(p, data[2:], c)
- if ret == 0 {
- return 0, nil
- }
-
- return ret + 2, node
- }
-
- if len(data) > 4 && data[1] == c && data[2] == c && data[3] != c {
- if c == '~' || isspace(data[3]) {
- return 0, nil
- }
- ret, node := helperTripleEmphasis(p, data, 3, c)
- if ret == 0 {
- return 0, nil
- }
-
- return ret + 3, node
- }
-
- return 0, nil
-}
-
-func codeSpan(p *Markdown, data []byte, offset int) (int, *Node) {
- data = data[offset:]
-
- nb := 0
-
- // count the number of backticks in the delimiter
- for nb < len(data) && data[nb] == '`' {
- nb++
- }
-
- // find the next delimiter
- i, end := 0, 0
- for end = nb; end < len(data) && i < nb; end++ {
- if data[end] == '`' {
- i++
- } else {
- i = 0
- }
- }
-
- // no matching delimiter?
- if i < nb && end >= len(data) {
- return 0, nil
- }
-
- // trim outside whitespace
- fBegin := nb
- for fBegin < end && data[fBegin] == ' ' {
- fBegin++
- }
-
- fEnd := end - nb
- for fEnd > fBegin && data[fEnd-1] == ' ' {
- fEnd--
- }
-
- // render the code span
- if fBegin != fEnd {
- code := NewNode(Code)
- code.Literal = data[fBegin:fEnd]
- return end, code
- }
-
- return end, nil
-}
-
-// newline preceded by two spaces becomes <br>
-func maybeLineBreak(p *Markdown, data []byte, offset int) (int, *Node) {
- origOffset := offset
- for offset < len(data) && data[offset] == ' ' {
- offset++
- }
-
- if offset < len(data) && data[offset] == '\n' {
- if offset-origOffset >= 2 {
- return offset - origOffset + 1, NewNode(Hardbreak)
- }
- return offset - origOffset, nil
- }
- return 0, nil
-}
-
-// newline without two spaces works when HardLineBreak is enabled
-func lineBreak(p *Markdown, data []byte, offset int) (int, *Node) {
- if p.extensions&HardLineBreak != 0 {
- return 1, NewNode(Hardbreak)
- }
- return 0, nil
-}
-
-type linkType int
-
-const (
- linkNormal linkType = iota
- linkImg
- linkDeferredFootnote
- linkInlineFootnote
-)
-
-func isReferenceStyleLink(data []byte, pos int, t linkType) bool {
- if t == linkDeferredFootnote {
- return false
- }
- return pos < len(data)-1 && data[pos] == '[' && data[pos+1] != '^'
-}
-
-func maybeImage(p *Markdown, data []byte, offset int) (int, *Node) {
- if offset < len(data)-1 && data[offset+1] == '[' {
- return link(p, data, offset)
- }
- return 0, nil
-}
-
-func maybeInlineFootnote(p *Markdown, data []byte, offset int) (int, *Node) {
- if offset < len(data)-1 && data[offset+1] == '[' {
- return link(p, data, offset)
- }
- return 0, nil
-}
-
-// '[': parse a link or an image or a footnote
-func link(p *Markdown, data []byte, offset int) (int, *Node) {
- // no links allowed inside regular links, footnote, and deferred footnotes
- if p.insideLink && (offset > 0 && data[offset-1] == '[' || len(data)-1 > offset && data[offset+1] == '^') {
- return 0, nil
- }
-
- var t linkType
- switch {
- // special case: ![^text] == deferred footnote (that follows something with
- // an exclamation point)
- case p.extensions&Footnotes != 0 && len(data)-1 > offset && data[offset+1] == '^':
- t = linkDeferredFootnote
- // ![alt] == image
- case offset >= 0 && data[offset] == '!':
- t = linkImg
- offset++
- // ^[text] == inline footnote
- // [^refId] == deferred footnote
- case p.extensions&Footnotes != 0:
- if offset >= 0 && data[offset] == '^' {
- t = linkInlineFootnote
- offset++
- } else if len(data)-1 > offset && data[offset+1] == '^' {
- t = linkDeferredFootnote
- }
- // [text] == regular link
- default:
- t = linkNormal
- }
-
- data = data[offset:]
-
- var (
- i = 1
- noteID int
- title, link, altContent []byte
- textHasNl = false
- )
-
- if t == linkDeferredFootnote {
- i++
- }
-
- // look for the matching closing bracket
- for level := 1; level > 0 && i < len(data); i++ {
- switch {
- case data[i] == '\n':
- textHasNl = true
-
- case data[i-1] == '\\':
- continue
-
- case data[i] == '[':
- level++
-
- case data[i] == ']':
- level--
- if level <= 0 {
- i-- // compensate for extra i++ in for loop
- }
- }
- }
-
- if i >= len(data) {
- return 0, nil
- }
-
- txtE := i
- i++
- var footnoteNode *Node
-
- // skip any amount of whitespace or newline
- // (this is much more lax than original markdown syntax)
- for i < len(data) && isspace(data[i]) {
- i++
- }
-
- // inline style link
- switch {
- case i < len(data) && data[i] == '(':
- // skip initial whitespace
- i++
-
- for i < len(data) && isspace(data[i]) {
- i++
- }
-
- linkB := i
-
- // look for link end: ' " )
- findlinkend:
- for i < len(data) {
- switch {
- case data[i] == '\\':
- i += 2
-
- case data[i] == ')' || data[i] == '\'' || data[i] == '"':
- break findlinkend
-
- default:
- i++
- }
- }
-
- if i >= len(data) {
- return 0, nil
- }
- linkE := i
-
- // look for title end if present
- titleB, titleE := 0, 0
- if data[i] == '\'' || data[i] == '"' {
- i++
- titleB = i
-
- findtitleend:
- for i < len(data) {
- switch {
- case data[i] == '\\':
- i += 2
-
- case data[i] == ')':
- break findtitleend
-
- default:
- i++
- }
- }
-
- if i >= len(data) {
- return 0, nil
- }
-
- // skip whitespace after title
- titleE = i - 1
- for titleE > titleB && isspace(data[titleE]) {
- titleE--
- }
-
- // check for closing quote presence
- if data[titleE] != '\'' && data[titleE] != '"' {
- titleB, titleE = 0, 0
- linkE = i
- }
- }
-
- // remove whitespace at the end of the link
- for linkE > linkB && isspace(data[linkE-1]) {
- linkE--
- }
-
- // remove optional angle brackets around the link
- if data[linkB] == '<' {
- linkB++
- }
- if data[linkE-1] == '>' {
- linkE--
- }
-
- // build escaped link and title
- if linkE > linkB {
- link = data[linkB:linkE]
- }
-
- if titleE > titleB {
- title = data[titleB:titleE]
- }
-
- i++
-
- // reference style link
- case isReferenceStyleLink(data, i, t):
- var id []byte
- altContentConsidered := false
-
- // look for the id
- i++
- linkB := i
- for i < len(data) && data[i] != ']' {
- i++
- }
- if i >= len(data) {
- return 0, nil
- }
- linkE := i
-
- // find the reference
- if linkB == linkE {
- if textHasNl {
- var b bytes.Buffer
-
- for j := 1; j < txtE; j++ {
- switch {
- case data[j] != '\n':
- b.WriteByte(data[j])
- case data[j-1] != ' ':
- b.WriteByte(' ')
- }
- }
-
- id = b.Bytes()
- } else {
- id = data[1:txtE]
- altContentConsidered = true
- }
- } else {
- id = data[linkB:linkE]
- }
-
- // find the reference with matching id
- lr, ok := p.getRef(string(id))
- if !ok {
- return 0, nil
- }
-
- // keep link and title from reference
- link = lr.link
- title = lr.title
- if altContentConsidered {
- altContent = lr.text
- }
- i++
-
- // shortcut reference style link or reference or inline footnote
- default:
- var id []byte
-
- // craft the id
- if textHasNl {
- var b bytes.Buffer
-
- for j := 1; j < txtE; j++ {
- switch {
- case data[j] != '\n':
- b.WriteByte(data[j])
- case data[j-1] != ' ':
- b.WriteByte(' ')
- }
- }
-
- id = b.Bytes()
- } else {
- if t == linkDeferredFootnote {
- id = data[2:txtE] // get rid of the ^
- } else {
- id = data[1:txtE]
- }
- }
-
- footnoteNode = NewNode(Item)
- if t == linkInlineFootnote {
- // create a new reference
- noteID = len(p.notes) + 1
-
- var fragment []byte
- if len(id) > 0 {
- if len(id) < 16 {
- fragment = make([]byte, len(id))
- } else {
- fragment = make([]byte, 16)
- }
- copy(fragment, slugify(id))
- } else {
- fragment = append([]byte("footnote-"), []byte(strconv.Itoa(noteID))...)
- }
-
- ref := &reference{
- noteID: noteID,
- hasBlock: false,
- link: fragment,
- title: id,
- footnote: footnoteNode,
- }
-
- p.notes = append(p.notes, ref)
-
- link = ref.link
- title = ref.title
- } else {
- // find the reference with matching id
- lr, ok := p.getRef(string(id))
- if !ok {
- return 0, nil
- }
-
- if t == linkDeferredFootnote {
- lr.noteID = len(p.notes) + 1
- lr.footnote = footnoteNode
- p.notes = append(p.notes, lr)
- }
-
- // keep link and title from reference
- link = lr.link
- // if inline footnote, title == footnote contents
- title = lr.title
- noteID = lr.noteID
- }
-
- // rewind the whitespace
- i = txtE + 1
- }
-
- var uLink []byte
- if t == linkNormal || t == linkImg {
- if len(link) > 0 {
- var uLinkBuf bytes.Buffer
- unescapeText(&uLinkBuf, link)
- uLink = uLinkBuf.Bytes()
- }
-
- // links need something to click on and somewhere to go
- if len(uLink) == 0 || (t == linkNormal && txtE <= 1) {
- return 0, nil
- }
- }
-
- // call the relevant rendering function
- var linkNode *Node
- switch t {
- case linkNormal:
- linkNode = NewNode(Link)
- linkNode.Destination = normalizeURI(uLink)
- linkNode.Title = title
- if len(altContent) > 0 {
- linkNode.AppendChild(text(altContent))
- } else {
- // links cannot contain other links, so turn off link parsing
- // temporarily and recurse
- insideLink := p.insideLink
- p.insideLink = true
- p.inline(linkNode, data[1:txtE])
- p.insideLink = insideLink
- }
-
- case linkImg:
- linkNode = NewNode(Image)
- linkNode.Destination = uLink
- linkNode.Title = title
- linkNode.AppendChild(text(data[1:txtE]))
- i++
-
- case linkInlineFootnote, linkDeferredFootnote:
- linkNode = NewNode(Link)
- linkNode.Destination = link
- linkNode.Title = title
- linkNode.NoteID = noteID
- linkNode.Footnote = footnoteNode
- if t == linkInlineFootnote {
- i++
- }
-
- default:
- return 0, nil
- }
-
- return i, linkNode
-}
-
-func (p *Markdown) inlineHTMLComment(data []byte) int {
- if len(data) < 5 {
- return 0
- }
- if data[0] != '<' || data[1] != '!' || data[2] != '-' || data[3] != '-' {
- return 0
- }
- i := 5
- // scan for an end-of-comment marker, across lines if necessary
- for i < len(data) && !(data[i-2] == '-' && data[i-1] == '-' && data[i] == '>') {
- i++
- }
- // no end-of-comment marker
- if i >= len(data) {
- return 0
- }
- return i + 1
-}
-
-func stripMailto(link []byte) []byte {
- if bytes.HasPrefix(link, []byte("mailto://")) {
- return link[9:]
- } else if bytes.HasPrefix(link, []byte("mailto:")) {
- return link[7:]
- } else {
- return link
- }
-}
-
-// autolinkType specifies a kind of autolink that gets detected.
-type autolinkType int
-
-// These are the possible flag values for the autolink renderer.
-const (
- notAutolink autolinkType = iota
- normalAutolink
- emailAutolink
-)
-
-// '<' when tags or autolinks are allowed
-func leftAngle(p *Markdown, data []byte, offset int) (int, *Node) {
- data = data[offset:]
- altype, end := tagLength(data)
- if size := p.inlineHTMLComment(data); size > 0 {
- end = size
- }
- if end > 2 {
- if altype != notAutolink {
- var uLink bytes.Buffer
- unescapeText(&uLink, data[1:end+1-2])
- if uLink.Len() > 0 {
- link := uLink.Bytes()
- node := NewNode(Link)
- node.Destination = link
- if altype == emailAutolink {
- node.Destination = append([]byte("mailto:"), link...)
- }
- node.AppendChild(text(stripMailto(link)))
- return end, node
- }
- } else {
- htmlTag := NewNode(HTMLSpan)
- htmlTag.Literal = data[:end]
- return end, htmlTag
- }
- }
-
- return end, nil
-}
-
-// '\\' backslash escape
-var escapeChars = []byte("\\`*_{}[]()#+-.!:|&<>~")
-
-func escape(p *Markdown, data []byte, offset int) (int, *Node) {
- data = data[offset:]
-
- if len(data) > 1 {
- if p.extensions&BackslashLineBreak != 0 && data[1] == '\n' {
- return 2, NewNode(Hardbreak)
- }
- if bytes.IndexByte(escapeChars, data[1]) < 0 {
- return 0, nil
- }
-
- return 2, text(data[1:2])
- }
-
- return 2, nil
-}
-
-func unescapeText(ob *bytes.Buffer, src []byte) {
- i := 0
- for i < len(src) {
- org := i
- for i < len(src) && src[i] != '\\' {
- i++
- }
-
- if i > org {
- ob.Write(src[org:i])
- }
-
- if i+1 >= len(src) {
- break
- }
-
- ob.WriteByte(src[i+1])
- i += 2
- }
-}
-
-// '&' escaped when it doesn't belong to an entity
-// valid entities are assumed to be anything matching &#?[A-Za-z0-9]+;
-func entity(p *Markdown, data []byte, offset int) (int, *Node) {
- data = data[offset:]
-
- end := 1
-
- if end < len(data) && data[end] == '#' {
- end++
- }
-
- for end < len(data) && isalnum(data[end]) {
- end++
- }
-
- if end < len(data) && data[end] == ';' {
- end++ // real entity
- } else {
- return 0, nil // lone '&'
- }
-
- ent := data[:end]
- // undo &amp; escaping or it will be converted to &amp;amp; by another
- // escaper in the renderer
- if bytes.Equal(ent, []byte("&amp;")) {
- ent = []byte{'&'}
- }
-
- return end, text(ent)
-}
-
-func linkEndsWithEntity(data []byte, linkEnd int) bool {
- entityRanges := htmlEntityRe.FindAllIndex(data[:linkEnd], -1)
- return entityRanges != nil && entityRanges[len(entityRanges)-1][1] == linkEnd
-}
-
-// hasPrefixCaseInsensitive is a custom implementation of
-//
-// strings.HasPrefix(strings.ToLower(s), prefix)
-//
-// we rolled our own because ToLower pulls in a huge machinery of lowercasing
-// anything from Unicode and that's very slow. Since this func will only be
-// used on ASCII protocol prefixes, we can take shortcuts.
-func hasPrefixCaseInsensitive(s, prefix []byte) bool {
- if len(s) < len(prefix) {
- return false
- }
- delta := byte('a' - 'A')
- for i, b := range prefix {
- if b != s[i] && b != s[i]+delta {
- return false
- }
- }
- return true
-}
-
-var protocolPrefixes = [][]byte{
- []byte("http://"),
- []byte("https://"),
- []byte("ftp://"),
- []byte("file://"),
- []byte("mailto:"),
-}
-
-const shortestPrefix = 6 // len("ftp://"), the shortest of the above
-
-func maybeAutoLink(p *Markdown, data []byte, offset int) (int, *Node) {
- // quick check to rule out most false hits
- if p.insideLink || len(data) < offset+shortestPrefix {
- return 0, nil
- }
- for _, prefix := range protocolPrefixes {
- endOfHead := offset + 8 // 8 is the len() of the longest prefix
- if endOfHead > len(data) {
- endOfHead = len(data)
- }
- if hasPrefixCaseInsensitive(data[offset:endOfHead], prefix) {
- return autoLink(p, data, offset)
- }
- }
- return 0, nil
-}
-
-func autoLink(p *Markdown, data []byte, offset int) (int, *Node) {
- // Now a more expensive check to see if we're not inside an anchor element
- anchorStart := offset
- offsetFromAnchor := 0
- for anchorStart > 0 && data[anchorStart] != '<' {
- anchorStart--
- offsetFromAnchor++
- }
-
- anchorStr := anchorRe.Find(data[anchorStart:])
- if anchorStr != nil {
- anchorClose := NewNode(HTMLSpan)
- anchorClose.Literal = anchorStr[offsetFromAnchor:]
- return len(anchorStr) - offsetFromAnchor, anchorClose
- }
-
- // scan backward for a word boundary
- rewind := 0
- for offset-rewind > 0 && rewind <= 7 && isletter(data[offset-rewind-1]) {
- rewind++
- }
- if rewind > 6 { // longest supported protocol is "mailto" which has 6 letters
- return 0, nil
- }
-
- origData := data
- data = data[offset-rewind:]
-
- if !isSafeLink(data) {
- return 0, nil
- }
-
- linkEnd := 0
- for linkEnd < len(data) && !isEndOfLink(data[linkEnd]) {
- linkEnd++
- }
-
- // Skip punctuation at the end of the link
- if (data[linkEnd-1] == '.' || data[linkEnd-1] == ',') && data[linkEnd-2] != '\\' {
- linkEnd--
- }
-
- // But don't skip semicolon if it's a part of escaped entity:
- if data[linkEnd-1] == ';' && data[linkEnd-2] != '\\' && !linkEndsWithEntity(data, linkEnd) {
- linkEnd--
- }
-
- // See if the link finishes with a punctuation sign that can be closed.
- var copen byte
- switch data[linkEnd-1] {
- case '"':
- copen = '"'
- case '\'':
- copen = '\''
- case ')':
- copen = '('
- case ']':
- copen = '['
- case '}':
- copen = '{'
- default:
- copen = 0
- }
-
- if copen != 0 {
- bufEnd := offset - rewind + linkEnd - 2
-
- openDelim := 1
-
- /* Try to close the final punctuation sign in this same line;
- * if we managed to close it outside of the URL, that means that it's
- * not part of the URL. If it closes inside the URL, that means it
- * is part of the URL.
- *
- * Examples:
- *
- * foo http://www.pokemon.com/Pikachu_(Electric) bar
- * => http://www.pokemon.com/Pikachu_(Electric)
- *
- * foo (http://www.pokemon.com/Pikachu_(Electric)) bar
- * => http://www.pokemon.com/Pikachu_(Electric)
- *
- * foo http://www.pokemon.com/Pikachu_(Electric)) bar
- * => http://www.pokemon.com/Pikachu_(Electric))
- *
- * (foo http://www.pokemon.com/Pikachu_(Electric)) bar
- * => foo http://www.pokemon.com/Pikachu_(Electric)
- */
-
- for bufEnd >= 0 && origData[bufEnd] != '\n' && openDelim != 0 {
- if origData[bufEnd] == data[linkEnd-1] {
- openDelim++
- }
-
- if origData[bufEnd] == copen {
- openDelim--
- }
-
- bufEnd--
- }
-
- if openDelim == 0 {
- linkEnd--
- }
- }
-
- var uLink bytes.Buffer
- unescapeText(&uLink, data[:linkEnd])
-
- if uLink.Len() > 0 {
- node := NewNode(Link)
- node.Destination = uLink.Bytes()
- node.AppendChild(text(uLink.Bytes()))
- return linkEnd, node
- }
-
- return linkEnd, nil
-}
-
-func isEndOfLink(char byte) bool {
- return isspace(char) || char == '<'
-}
-
-var validUris = [][]byte{[]byte("http://"), []byte("https://"), []byte("ftp://"), []byte("mailto://")}
-var validPaths = [][]byte{[]byte("/"), []byte("./"), []byte("../")}
-
-func isSafeLink(link []byte) bool {
- for _, path := range validPaths {
- if len(link) >= len(path) && bytes.Equal(link[:len(path)], path) {
- if len(link) == len(path) {
- return true
- } else if isalnum(link[len(path)]) {
- return true
- }
- }
- }
-
- for _, prefix := range validUris {
- // TODO: handle unicode here
- // case-insensitive prefix test
- if len(link) > len(prefix) && bytes.Equal(bytes.ToLower(link[:len(prefix)]), prefix) && isalnum(link[len(prefix)]) {
- return true
- }
- }
-
- return false
-}
-
-// return the length of the given tag, or 0 is it's not valid
-func tagLength(data []byte) (autolink autolinkType, end int) {
- var i, j int
-
- // a valid tag can't be shorter than 3 chars
- if len(data) < 3 {
- return notAutolink, 0
- }
-
- // begins with a '<' optionally followed by '/', followed by letter or number
- if data[0] != '<' {
- return notAutolink, 0
- }
- if data[1] == '/' {
- i = 2
- } else {
- i = 1
- }
-
- if !isalnum(data[i]) {
- return notAutolink, 0
- }
-
- // scheme test
- autolink = notAutolink
-
- // try to find the beginning of an URI
- for i < len(data) && (isalnum(data[i]) || data[i] == '.' || data[i] == '+' || data[i] == '-') {
- i++
- }
-
- if i > 1 && i < len(data) && data[i] == '@' {
- if j = isMailtoAutoLink(data[i:]); j != 0 {
- return emailAutolink, i + j
- }
- }
-
- if i > 2 && i < len(data) && data[i] == ':' {
- autolink = normalAutolink
- i++
- }
-
- // complete autolink test: no whitespace or ' or "
- switch {
- case i >= len(data):
- autolink = notAutolink
- case autolink != notAutolink:
- j = i
-
- for i < len(data) {
- if data[i] == '\\' {
- i += 2
- } else if data[i] == '>' || data[i] == '\'' || data[i] == '"' || isspace(data[i]) {
- break
- } else {
- i++
- }
-
- }
-
- if i >= len(data) {
- return autolink, 0
- }
- if i > j && data[i] == '>' {
- return autolink, i + 1
- }
-
- // one of the forbidden chars has been found
- autolink = notAutolink
- }
- i += bytes.IndexByte(data[i:], '>')
- if i < 0 {
- return autolink, 0
- }
- return autolink, i + 1
-}
-
-// look for the address part of a mail autolink and '>'
-// this is less strict than the original markdown e-mail address matching
-func isMailtoAutoLink(data []byte) int {
- nb := 0
-
- // address is assumed to be: [-@._a-zA-Z0-9]+ with exactly one '@'
- for i := 0; i < len(data); i++ {
- if isalnum(data[i]) {
- continue
- }
-
- switch data[i] {
- case '@':
- nb++
-
- case '-', '.', '_':
- break
-
- case '>':
- if nb == 1 {
- return i + 1
- }
- return 0
- default:
- return 0
- }
- }
-
- return 0
-}
-
-// look for the next emph char, skipping other constructs
-func helperFindEmphChar(data []byte, c byte) int {
- i := 0
-
- for i < len(data) {
- for i < len(data) && data[i] != c && data[i] != '`' && data[i] != '[' {
- i++
- }
- if i >= len(data) {
- return 0
- }
- // do not count escaped chars
- if i != 0 && data[i-1] == '\\' {
- i++
- continue
- }
- if data[i] == c {
- return i
- }
-
- if data[i] == '`' {
- // skip a code span
- tmpI := 0
- i++
- for i < len(data) && data[i] != '`' {
- if tmpI == 0 && data[i] == c {
- tmpI = i
- }
- i++
- }
- if i >= len(data) {
- return tmpI
- }
- i++
- } else if data[i] == '[' {
- // skip a link
- tmpI := 0
- i++
- for i < len(data) && data[i] != ']' {
- if tmpI == 0 && data[i] == c {
- tmpI = i
- }
- i++
- }
- i++
- for i < len(data) && (data[i] == ' ' || data[i] == '\n') {
- i++
- }
- if i >= len(data) {
- return tmpI
- }
- if data[i] != '[' && data[i] != '(' { // not a link
- if tmpI > 0 {
- return tmpI
- }
- continue
- }
- cc := data[i]
- i++
- for i < len(data) && data[i] != cc {
- if tmpI == 0 && data[i] == c {
- return i
- }
- i++
- }
- if i >= len(data) {
- return tmpI
- }
- i++
- }
- }
- return 0
-}
-
-func helperEmphasis(p *Markdown, data []byte, c byte) (int, *Node) {
- i := 0
-
- // skip one symbol if coming from emph3
- if len(data) > 1 && data[0] == c && data[1] == c {
- i = 1
- }
-
- for i < len(data) {
- length := helperFindEmphChar(data[i:], c)
- if length == 0 {
- return 0, nil
- }
- i += length
- if i >= len(data) {
- return 0, nil
- }
-
- if i+1 < len(data) && data[i+1] == c {
- i++
- continue
- }
-
- if data[i] == c && !isspace(data[i-1]) {
-
- if p.extensions&NoIntraEmphasis != 0 {
- if !(i+1 == len(data) || isspace(data[i+1]) || ispunct(data[i+1])) {
- continue
- }
- }
-
- emph := NewNode(Emph)
- p.inline(emph, data[:i])
- return i + 1, emph
- }
- }
-
- return 0, nil
-}
-
-func helperDoubleEmphasis(p *Markdown, data []byte, c byte) (int, *Node) {
- i := 0
-
- for i < len(data) {
- length := helperFindEmphChar(data[i:], c)
- if length == 0 {
- return 0, nil
- }
- i += length
-
- if i+1 < len(data) && data[i] == c && data[i+1] == c && i > 0 && !isspace(data[i-1]) {
- nodeType := Strong
- if c == '~' {
- nodeType = Del
- }
- node := NewNode(nodeType)
- p.inline(node, data[:i])
- return i + 2, node
- }
- i++
- }
- return 0, nil
-}
-
-func helperTripleEmphasis(p *Markdown, data []byte, offset int, c byte) (int, *Node) {
- i := 0
- origData := data
- data = data[offset:]
-
- for i < len(data) {
- length := helperFindEmphChar(data[i:], c)
- if length == 0 {
- return 0, nil
- }
- i += length
-
- // skip whitespace preceded symbols
- if data[i] != c || isspace(data[i-1]) {
- continue
- }
-
- switch {
- case i+2 < len(data) && data[i+1] == c && data[i+2] == c:
- // triple symbol found
- strong := NewNode(Strong)
- em := NewNode(Emph)
- strong.AppendChild(em)
- p.inline(em, data[:i])
- return i + 3, strong
- case (i+1 < len(data) && data[i+1] == c):
- // double symbol found, hand over to emph1
- length, node := helperEmphasis(p, origData[offset-2:], c)
- if length == 0 {
- return 0, nil
- }
- return length - 2, node
- default:
- // single symbol found, hand over to emph2
- length, node := helperDoubleEmphasis(p, origData[offset-1:], c)
- if length == 0 {
- return 0, nil
- }
- return length - 1, node
- }
- }
- return 0, nil
-}
-
-func text(s []byte) *Node {
- node := NewNode(Text)
- node.Literal = s
- return node
-}
-
-func normalizeURI(s []byte) []byte {
- return s // TODO: implement
-}
diff --git a/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/markdown.go b/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/markdown.go
deleted file mode 100644
index 4d0a831..0000000
--- a/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/markdown.go
+++ /dev/null
@@ -1,945 +0,0 @@
-// Blackfriday Markdown Processor
-// Available at http://github.com/russross/blackfriday
-//
-// Copyright © 2011 Russ Ross <russ@russross.com>.
-// Distributed under the Simplified BSD License.
-// See README.md for details.
-
-//nolint:gocritic,wastedassign,unused,revive,govet // ignore blackfriday
-package blackfriday
-
-import (
- "bytes"
- "fmt"
- "io"
- "strings"
- "unicode/utf8"
-)
-
-//
-// Markdown parsing and processing
-//
-
-// Version string of the package. Appears in the rendered document when
-// CompletePage flag is on.
-const Version = "2.0"
-
-// Extensions is a bitwise or'ed collection of enabled Blackfriday's
-// extensions.
-type Extensions int
-
-// These are the supported markdown parsing extensions.
-// OR these values together to select multiple extensions.
-const (
- NoExtensions Extensions = 0
- NoIntraEmphasis Extensions = 1 << iota // Ignore emphasis markers inside words
- Tables // Render tables
- FencedCode // Render fenced code blocks
- Autolink // Detect embedded URLs that are not explicitly marked
- Strikethrough // Strikethrough text using ~~test~~
- LaxHTMLBlocks // Loosen up HTML block parsing rules
- SpaceHeadings // Be strict about prefix heading rules
- HardLineBreak // Translate newlines into line breaks
- TabSizeEight // Expand tabs to eight spaces instead of four
- Footnotes // Pandoc-style footnotes
- NoEmptyLineBeforeBlock // No need to insert an empty line to start a (code, quote, ordered list, unordered list) block
- HeadingIDs // specify heading IDs with {#id}
- Titleblock // Titleblock ala pandoc
- AutoHeadingIDs // Create the heading ID from the text
- BackslashLineBreak // Translate trailing backslashes into line breaks
- DefinitionLists // Render definition lists
-
- CommonHTMLFlags HTMLFlags = UseXHTML | Smartypants |
- SmartypantsFractions | SmartypantsDashes | SmartypantsLatexDashes
-
- CommonExtensions Extensions = NoIntraEmphasis | Tables | FencedCode |
- Autolink | Strikethrough | SpaceHeadings | HeadingIDs |
- BackslashLineBreak | DefinitionLists
-)
-
-// ListType contains bitwise or'ed flags for list and list item objects.
-type ListType int
-
-// These are the possible flag values for the ListItem renderer.
-// Multiple flag values may be ORed together.
-// These are mostly of interest if you are writing a new output format.
-const (
- ListTypeOrdered ListType = 1 << iota
- ListTypeDefinition
- ListTypeTerm
-
- ListItemContainsBlock
- ListItemBeginningOfList // TODO: figure out if this is of any use now
- ListItemEndOfList
-)
-
-// CellAlignFlags holds a type of alignment in a table cell.
-type CellAlignFlags int
-
-// These are the possible flag values for the table cell renderer.
-// Only a single one of these values will be used; they are not ORed together.
-// These are mostly of interest if you are writing a new output format.
-const (
- TableAlignmentLeft CellAlignFlags = 1 << iota
- TableAlignmentRight
- TableAlignmentCenter = (TableAlignmentLeft | TableAlignmentRight)
-)
-
-// The size of a tab stop.
-const (
- TabSizeDefault = 4
- TabSizeDouble = 8
-)
-
-// blockTags is a set of tags that are recognized as HTML block tags.
-// Any of these can be included in markdown text without special escaping.
-var blockTags = map[string]struct{}{
- "blockquote": {},
- "del": {},
- "div": {},
- "dl": {},
- "fieldset": {},
- "form": {},
- "h1": {},
- "h2": {},
- "h3": {},
- "h4": {},
- "h5": {},
- "h6": {},
- "iframe": {},
- "ins": {},
- "math": {},
- "noscript": {},
- "ol": {},
- "pre": {},
- "p": {},
- "script": {},
- "style": {},
- "table": {},
- "ul": {},
-
- // HTML5
- "address": {},
- "article": {},
- "aside": {},
- "canvas": {},
- "figcaption": {},
- "figure": {},
- "footer": {},
- "header": {},
- "hgroup": {},
- "main": {},
- "nav": {},
- "output": {},
- "progress": {},
- "section": {},
- "video": {},
-}
-
-// Renderer is the rendering interface. This is mostly of interest if you are
-// implementing a new rendering format.
-//
-// Only an HTML implementation is provided in this repository, see the README
-// for external implementations.
-type Renderer interface {
- // RenderNode is the main rendering method. It will be called once for
- // every leaf node and twice for every non-leaf node (first with
- // entering=true, then with entering=false). The method should write its
- // rendition of the node to the supplied writer w.
- RenderNode(w io.Writer, node *Node, entering bool) WalkStatus
-
- // RenderHeader is a method that allows the renderer to produce some
- // content preceding the main body of the output document. The header is
- // understood in the broad sense here. For example, the default HTML
- // renderer will write not only the HTML document preamble, but also the
- // table of contents if it was requested.
- //
- // The method will be passed an entire document tree, in case a particular
- // implementation needs to inspect it to produce output.
- //
- // The output should be written to the supplied writer w. If your
- // implementation has no header to write, supply an empty implementation.
- RenderHeader(w io.Writer, ast *Node)
-
- // RenderFooter is a symmetric counterpart of RenderHeader.
- RenderFooter(w io.Writer, ast *Node)
-}
-
-// Callback functions for inline parsing. One such function is defined
-// for each character that triggers a response when parsing inline data.
-type inlineParser func(p *Markdown, data []byte, offset int) (int, *Node)
-
-// Markdown is a type that holds extensions and the runtime state used by
-// Parse, and the renderer. You can not use it directly, construct it with New.
-type Markdown struct {
- renderer Renderer
- referenceOverride ReferenceOverrideFunc
- refs map[string]*reference
- inlineCallback [256]inlineParser
- extensions Extensions
- nesting int
- maxNesting int
- insideLink bool
-
- // Footnotes need to be ordered as well as available to quickly check for
- // presence. If a ref is also a footnote, it's stored both in refs and here
- // in notes. Slice is nil if footnotes not enabled.
- notes []*reference
-
- doc *Node
- tip *Node // = doc
- oldTip *Node
- lastMatchedContainer *Node // = doc
- allClosed bool
-}
-
-func (p *Markdown) getRef(refid string) (ref *reference, found bool) {
- if p.referenceOverride != nil {
- r, overridden := p.referenceOverride(refid)
- if overridden {
- if r == nil {
- return nil, false
- }
- return &reference{
- link: []byte(r.Link),
- title: []byte(r.Title),
- noteID: 0,
- hasBlock: false,
- text: []byte(r.Text)}, true
- }
- }
- // refs are case insensitive
- ref, found = p.refs[strings.ToLower(refid)]
- return ref, found
-}
-
-func (p *Markdown) finalize(block *Node) {
- above := block.Parent
- block.open = false
- p.tip = above
-}
-
-func (p *Markdown) addChild(node NodeType, offset uint32) *Node {
- return p.addExistingChild(NewNode(node), offset)
-}
-
-func (p *Markdown) addExistingChild(node *Node, offset uint32) *Node {
- for !p.tip.canContain(node.Type) {
- p.finalize(p.tip)
- }
- p.tip.AppendChild(node)
- p.tip = node
- return node
-}
-
-func (p *Markdown) closeUnmatchedBlocks() {
- if !p.allClosed {
- for p.oldTip != p.lastMatchedContainer {
- parent := p.oldTip.Parent
- p.finalize(p.oldTip)
- p.oldTip = parent
- }
- p.allClosed = true
- }
-}
-
-//
-//
-// Public interface
-//
-//
-
-// Reference represents the details of a link.
-// See the documentation in Options for more details on use-case.
-type Reference struct {
- // Link is usually the URL the reference points to.
- Link string
- // Title is the alternate text describing the link in more detail.
- Title string
- // Text is the optional text to override the ref with if the syntax used was
- // [refid][]
- Text string
-}
-
-// ReferenceOverrideFunc is expected to be called with a reference string and
-// return either a valid Reference type that the reference string maps to or
-// nil. If overridden is false, the default reference logic will be executed.
-// See the documentation in Options for more details on use-case.
-type ReferenceOverrideFunc func(reference string) (ref *Reference, overridden bool)
-
-// New constructs a Markdown processor. You can use the same With* functions as
-// for Run() to customize parser's behavior and the renderer.
-func New(opts ...Option) *Markdown {
- var p Markdown
- for _, opt := range opts {
- opt(&p)
- }
- p.refs = make(map[string]*reference)
- p.maxNesting = 16
- p.insideLink = false
- docNode := NewNode(Document)
- p.doc = docNode
- p.tip = docNode
- p.oldTip = docNode
- p.lastMatchedContainer = docNode
- p.allClosed = true
- // register inline parsers
- p.inlineCallback[' '] = maybeLineBreak
- p.inlineCallback['*'] = emphasis
- p.inlineCallback['_'] = emphasis
- if p.extensions&Strikethrough != 0 {
- p.inlineCallback['~'] = emphasis
- }
- p.inlineCallback['`'] = codeSpan
- p.inlineCallback['\n'] = lineBreak
- p.inlineCallback['['] = link
- p.inlineCallback['<'] = leftAngle
- p.inlineCallback['\\'] = escape
- p.inlineCallback['&'] = entity
- p.inlineCallback['!'] = maybeImage
- p.inlineCallback['^'] = maybeInlineFootnote
- if p.extensions&Autolink != 0 {
- p.inlineCallback['h'] = maybeAutoLink
- p.inlineCallback['m'] = maybeAutoLink
- p.inlineCallback['f'] = maybeAutoLink
- p.inlineCallback['H'] = maybeAutoLink
- p.inlineCallback['M'] = maybeAutoLink
- p.inlineCallback['F'] = maybeAutoLink
- }
- if p.extensions&Footnotes != 0 {
- p.notes = make([]*reference, 0)
- }
- return &p
-}
-
-// Option customizes the Markdown processor's default behavior.
-type Option func(*Markdown)
-
-// WithRenderer allows you to override the default renderer.
-func WithRenderer(r Renderer) Option {
- return func(p *Markdown) {
- p.renderer = r
- }
-}
-
-// WithExtensions allows you to pick some of the many extensions provided by
-// Blackfriday. You can bitwise OR them.
-func WithExtensions(e Extensions) Option {
- return func(p *Markdown) {
- p.extensions = e
- }
-}
-
-// WithNoExtensions turns off all extensions and custom behavior.
-func WithNoExtensions() Option {
- return func(p *Markdown) {
- p.extensions = NoExtensions
- p.renderer = NewHTMLRenderer(HTMLRendererParameters{
- Flags: HTMLFlagsNone,
- })
- }
-}
-
-// WithRefOverride sets an optional function callback that is called every
-// time a reference is resolved.
-//
-// In Markdown, the link reference syntax can be made to resolve a link to
-// a reference instead of an inline URL, in one of the following ways:
-//
-// - [link text][refid]
-// - [refid][]
-//
-// Usually, the refid is defined at the bottom of the Markdown document. If
-// this override function is provided, the refid is passed to the override
-// function first, before consulting the defined refids at the bottom. If
-// the override function indicates an override did not occur, the refids at
-// the bottom will be used to fill in the link details.
-func WithRefOverride(o ReferenceOverrideFunc) Option {
- return func(p *Markdown) {
- p.referenceOverride = o
- }
-}
-
-// Run is the main entry point to Blackfriday. It parses and renders a
-// block of markdown-encoded text.
-//
-// The simplest invocation of Run takes one argument, input:
-//
-// output := Run(input)
-//
-// This will parse the input with CommonExtensions enabled and render it with
-// the default HTMLRenderer (with CommonHTMLFlags).
-//
-// Variadic arguments opts can customize the default behavior. Since Markdown
-// type does not contain exported fields, you can not use it directly. Instead,
-// use the With* functions. For example, this will call the most basic
-// functionality, with no extensions:
-//
-// output := Run(input, WithNoExtensions())
-//
-// You can use any number of With* arguments, even contradicting ones. They
-// will be applied in order of appearance and the latter will override the
-// former:
-//
-// output := Run(input, WithNoExtensions(), WithExtensions(exts),
-// WithRenderer(yourRenderer))
-func Run(input []byte, opts ...Option) []byte {
- r := NewHTMLRenderer(HTMLRendererParameters{
- Flags: CommonHTMLFlags,
- })
- optList := []Option{WithRenderer(r), WithExtensions(CommonExtensions)}
- optList = append(optList, opts...)
- parser := New(optList...)
- ast := parser.Parse(input)
- var buf bytes.Buffer
- parser.renderer.RenderHeader(&buf, ast)
- ast.Walk(func(node *Node, entering bool) WalkStatus {
- return parser.renderer.RenderNode(&buf, node, entering)
- })
- parser.renderer.RenderFooter(&buf, ast)
- return buf.Bytes()
-}
-
-// Parse is an entry point to the parsing part of Blackfriday. It takes an
-// input markdown document and produces a syntax tree for its contents. This
-// tree can then be rendered with a default or custom renderer, or
-// analyzed/transformed by the caller to whatever non-standard needs they have.
-// The return value is the root node of the syntax tree.
-func (p *Markdown) Parse(input []byte) *Node {
- p.block(input)
- // Walk the tree and finish up some of unfinished blocks
- for p.tip != nil {
- p.finalize(p.tip)
- }
- // Walk the tree again and process inline markdown in each block
- p.doc.Walk(func(node *Node, entering bool) WalkStatus {
- if node.Type == Paragraph || node.Type == Heading || node.Type == TableCell {
- p.inline(node, node.content)
- node.content = nil
- }
- return GoToNext
- })
- p.parseRefsToAST()
- return p.doc
-}
-
-func (p *Markdown) parseRefsToAST() {
- if p.extensions&Footnotes == 0 || len(p.notes) == 0 {
- return
- }
- p.tip = p.doc
- block := p.addBlock(List, nil)
- block.IsFootnotesList = true
- block.ListFlags = ListTypeOrdered
- flags := ListItemBeginningOfList
- // Note: this loop is intentionally explicit, not range-form. This is
- // because the body of the loop will append nested footnotes to p.notes and
- // we need to process those late additions. Range form would only walk over
- // the fixed initial set.
- for i := 0; i < len(p.notes); i++ {
- ref := p.notes[i]
- p.addExistingChild(ref.footnote, 0)
- block := ref.footnote
- block.ListFlags = flags | ListTypeOrdered
- block.RefLink = ref.link
- if ref.hasBlock {
- flags |= ListItemContainsBlock
- p.block(ref.title)
- } else {
- p.inline(block, ref.title)
- }
- flags &^= ListItemBeginningOfList | ListItemContainsBlock
- }
- above := block.Parent
- finalizeList(block)
- p.tip = above
- block.Walk(func(node *Node, entering bool) WalkStatus {
- if node.Type == Paragraph || node.Type == Heading {
- p.inline(node, node.content)
- node.content = nil
- }
- return GoToNext
- })
-}
-
-//
-// Link references
-//
-// This section implements support for references that (usually) appear
-// as footnotes in a document, and can be referenced anywhere in the document.
-// The basic format is:
-//
-// [1]: http://www.google.com/ "Google"
-// [2]: http://www.github.com/ "Github"
-//
-// Anywhere in the document, the reference can be linked by referring to its
-// label, i.e., 1 and 2 in this example, as in:
-//
-// This library is hosted on [Github][2], a git hosting site.
-//
-// Actual footnotes as specified in Pandoc and supported by some other Markdown
-// libraries such as php-markdown are also taken care of. They look like this:
-//
-// This sentence needs a bit of further explanation.[^note]
-//
-// [^note]: This is the explanation.
-//
-// Footnotes should be placed at the end of the document in an ordered list.
-// Inline footnotes such as:
-//
-// Inline footnotes^[Not supported.] also exist.
-//
-// are not yet supported.
-
-// reference holds all information necessary for a reference-style links or
-// footnotes.
-//
-// Consider this markdown with reference-style links:
-//
-// [link][ref]
-//
-// [ref]: /url/ "tooltip title"
-//
-// It will be ultimately converted to this HTML:
-//
-// <p><a href=\"/url/\" title=\"title\">link</a></p>
-//
-// And a reference structure will be populated as follows:
-//
-// p.refs["ref"] = &reference{
-// link: "/url/",
-// title: "tooltip title",
-// }
-//
-// Alternatively, reference can contain information about a footnote. Consider
-// this markdown:
-//
-// Text needing a footnote.[^a]
-//
-// [^a]: This is the note
-//
-// A reference structure will be populated as follows:
-//
-// p.refs["a"] = &reference{
-// link: "a",
-// title: "This is the note",
-// noteID: <some positive int>,
-// }
-//
-// TODO: As you can see, it begs for splitting into two dedicated structures
-// for refs and for footnotes.
-type reference struct {
- link []byte
- title []byte
- noteID int // 0 if not a footnote ref
- hasBlock bool
- footnote *Node // a link to the Item node within a list of footnotes
-
- text []byte // only gets populated by refOverride feature with Reference.Text
-}
-
-func (r *reference) String() string {
- return fmt.Sprintf("{link: %q, title: %q, text: %q, noteID: %d, hasBlock: %v}",
- r.link, r.title, r.text, r.noteID, r.hasBlock)
-}
-
-// Check whether or not data starts with a reference link.
-// If so, it is parsed and stored in the list of references
-// (in the render struct).
-// Returns the number of bytes to skip to move past it,
-// or zero if the first line is not a reference.
-func isReference(p *Markdown, data []byte, tabSize int) int {
- // up to 3 optional leading spaces
- if len(data) < 4 {
- return 0
- }
- i := 0
- for i < 3 && data[i] == ' ' {
- i++
- }
-
- noteID := 0
-
- // id part: anything but a newline between brackets
- if data[i] != '[' {
- return 0
- }
- i++
- if p.extensions&Footnotes != 0 {
- if i < len(data) && data[i] == '^' {
- // we can set it to anything here because the proper noteIds will
- // be assigned later during the second pass. It just has to be != 0
- noteID = 1
- i++
- }
- }
- idOffset := i
- for i < len(data) && data[i] != '\n' && data[i] != '\r' && data[i] != ']' {
- i++
- }
- if i >= len(data) || data[i] != ']' {
- return 0
- }
- idEnd := i
- // footnotes can have empty ID, like this: [^], but a reference can not be
- // empty like this: []. Break early if it's not a footnote and there's no ID
- if noteID == 0 && idOffset == idEnd {
- return 0
- }
- // spacer: colon (space | tab)* newline? (space | tab)*
- i++
- if i >= len(data) || data[i] != ':' {
- return 0
- }
- i++
- for i < len(data) && (data[i] == ' ' || data[i] == '\t') {
- i++
- }
- if i < len(data) && (data[i] == '\n' || data[i] == '\r') {
- i++
- if i < len(data) && data[i] == '\n' && data[i-1] == '\r' {
- i++
- }
- }
- for i < len(data) && (data[i] == ' ' || data[i] == '\t') {
- i++
- }
- if i >= len(data) {
- return 0
- }
-
- var (
- linkOffset, linkEnd int
- titleOffset, titleEnd int
- lineEnd int
- raw []byte
- hasBlock bool
- )
-
- if p.extensions&Footnotes != 0 && noteID != 0 {
- linkOffset, linkEnd, raw, hasBlock = scanFootnote(p, data, i, tabSize)
- lineEnd = linkEnd
- } else {
- linkOffset, linkEnd, titleOffset, titleEnd, lineEnd = scanLinkRef(p, data, i)
- }
- if lineEnd == 0 {
- return 0
- }
-
- // a valid ref has been found
-
- ref := &reference{
- noteID: noteID,
- hasBlock: hasBlock,
- }
-
- if noteID > 0 {
- // reusing the link field for the id since footnotes don't have links
- ref.link = data[idOffset:idEnd]
- // if footnote, it's not really a title, it's the contained text
- ref.title = raw
- } else {
- ref.link = data[linkOffset:linkEnd]
- ref.title = data[titleOffset:titleEnd]
- }
-
- // id matches are case-insensitive
- id := string(bytes.ToLower(data[idOffset:idEnd]))
-
- p.refs[id] = ref
-
- return lineEnd
-}
-
-func scanLinkRef(p *Markdown, data []byte, i int) (linkOffset, linkEnd, titleOffset, titleEnd, lineEnd int) {
- // link: whitespace-free sequence, optionally between angle brackets
- if data[i] == '<' {
- i++
- }
- linkOffset = i
- for i < len(data) && data[i] != ' ' && data[i] != '\t' && data[i] != '\n' && data[i] != '\r' {
- i++
- }
- linkEnd = i
- if data[linkOffset] == '<' && data[linkEnd-1] == '>' {
- linkOffset++
- linkEnd--
- }
-
- // optional spacer: (space | tab)* (newline | '\'' | '"' | '(' )
- for i < len(data) && (data[i] == ' ' || data[i] == '\t') {
- i++
- }
- if i < len(data) && data[i] != '\n' && data[i] != '\r' && data[i] != '\'' && data[i] != '"' && data[i] != '(' {
- return
- }
-
- // compute end-of-line
- if i >= len(data) || data[i] == '\r' || data[i] == '\n' {
- lineEnd = i
- }
- if i+1 < len(data) && data[i] == '\r' && data[i+1] == '\n' {
- lineEnd++
- }
-
- // optional (space|tab)* spacer after a newline
- if lineEnd > 0 {
- i = lineEnd + 1
- for i < len(data) && (data[i] == ' ' || data[i] == '\t') {
- i++
- }
- }
-
- // optional title: any non-newline sequence enclosed in '"() alone on its line
- if i+1 < len(data) && (data[i] == '\'' || data[i] == '"' || data[i] == '(') {
- i++
- titleOffset = i
-
- // look for EOL
- for i < len(data) && data[i] != '\n' && data[i] != '\r' {
- i++
- }
- if i+1 < len(data) && data[i] == '\n' && data[i+1] == '\r' {
- titleEnd = i + 1
- } else {
- titleEnd = i
- }
-
- // step back
- i--
- for i > titleOffset && (data[i] == ' ' || data[i] == '\t') {
- i--
- }
- if i > titleOffset && (data[i] == '\'' || data[i] == '"' || data[i] == ')') {
- lineEnd = titleEnd
- titleEnd = i
- }
- }
-
- return
-}
-
-// The first bit of this logic is the same as Parser.listItem, but the rest
-// is much simpler. This function simply finds the entire block and shifts it
-// over by one tab if it is indeed a block (just returns the line if it's not).
-// blockEnd is the end of the section in the input buffer, and contents is the
-// extracted text that was shifted over one tab. It will need to be rendered at
-// the end of the document.
-func scanFootnote(p *Markdown, data []byte, i, indentSize int) (blockStart, blockEnd int, contents []byte, hasBlock bool) {
- if i == 0 || len(data) == 0 {
- return
- }
-
- // skip leading whitespace on first line
- for i < len(data) && data[i] == ' ' {
- i++
- }
-
- blockStart = i
-
- // find the end of the line
- blockEnd = i
- for i < len(data) && data[i-1] != '\n' {
- i++
- }
-
- // get working buffer
- var raw bytes.Buffer
-
- // put the first line into the working buffer
- raw.Write(data[blockEnd:i])
- blockEnd = i
-
- // process the following lines
- containsBlankLine := false
-
-gatherLines:
- for blockEnd < len(data) {
- i++
-
- // find the end of this line
- for i < len(data) && data[i-1] != '\n' {
- i++
- }
-
- // if it is an empty line, guess that it is part of this item
- // and move on to the next line
- if p.isEmpty(data[blockEnd:i]) > 0 {
- containsBlankLine = true
- blockEnd = i
- continue
- }
-
- n := 0
- if n = isIndented(data[blockEnd:i], indentSize); n == 0 {
- // this is the end of the block.
- // we don't want to include this last line in the index.
- break gatherLines
- }
-
- // if there were blank lines before this one, insert a new one now
- if containsBlankLine {
- raw.WriteByte('\n')
- containsBlankLine = false
- }
-
- // get rid of that first tab, write to buffer
- raw.Write(data[blockEnd+n : i])
- hasBlock = true
-
- blockEnd = i
- }
-
- if data[blockEnd-1] != '\n' {
- raw.WriteByte('\n')
- }
-
- contents = raw.Bytes()
-
- return
-}
-
-//
-//
-// Miscellaneous helper functions
-//
-//
-
-// Test if a character is a punctuation symbol.
-// Taken from a private function in regexp in the stdlib.
-func ispunct(c byte) bool {
- for _, r := range []byte("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~") {
- if c == r {
- return true
- }
- }
- return false
-}
-
-// Test if a character is a whitespace character.
-func isspace(c byte) bool {
- return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v'
-}
-
-// Test if a character is letter.
-func isletter(c byte) bool {
- return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
-}
-
-// Test if a character is a letter or a digit.
-// TODO: check when this is looking for ASCII alnum and when it should use unicode
-func isalnum(c byte) bool {
- return (c >= '0' && c <= '9') || isletter(c)
-}
-
-// Replace tab characters with spaces, aligning to the next TAB_SIZE column.
-// always ends output with a newline
-func expandTabs(out *bytes.Buffer, line []byte, tabSize int) {
- // first, check for common cases: no tabs, or only tabs at beginning of line
- i, prefix := 0, 0
- slowcase := false
- for i = 0; i < len(line); i++ {
- if line[i] == '\t' {
- if prefix == i {
- prefix++
- } else {
- slowcase = true
- break
- }
- }
- }
-
- // no need to decode runes if all tabs are at the beginning of the line
- if !slowcase {
- for i = 0; i < prefix*tabSize; i++ {
- out.WriteByte(' ')
- }
- out.Write(line[prefix:])
- return
- }
-
- // the slow case: we need to count runes to figure out how
- // many spaces to insert for each tab
- column := 0
- i = 0
- for i < len(line) {
- start := i
- for i < len(line) && line[i] != '\t' {
- _, size := utf8.DecodeRune(line[i:])
- i += size
- column++
- }
-
- if i > start {
- out.Write(line[start:i])
- }
-
- if i >= len(line) {
- break
- }
-
- for {
- out.WriteByte(' ')
- column++
- if column%tabSize == 0 {
- break
- }
- }
-
- i++
- }
-}
-
-// Find if a line counts as indented or not.
-// Returns number of characters the indent is (0 = not indented).
-func isIndented(data []byte, indentSize int) int {
- if len(data) == 0 {
- return 0
- }
- if data[0] == '\t' {
- return 1
- }
- if len(data) < indentSize {
- return 0
- }
- for i := 0; i < indentSize; i++ {
- if data[i] != ' ' {
- return 0
- }
- }
- return indentSize
-}
-
-// Create a url-safe slug for fragments
-func slugify(in []byte) []byte {
- if len(in) == 0 {
- return in
- }
- out := make([]byte, 0, len(in))
- sym := false
-
- for _, ch := range in {
- if isalnum(ch) {
- sym = false
- out = append(out, ch)
- } else if sym {
- continue
- } else {
- out = append(out, '-')
- sym = true
- }
- }
- var a, b int
- var ch byte
- for a, ch = range out {
- if ch != '-' {
- break
- }
- }
- for b = len(out) - 1; b > 0; b-- {
- if out[b] != '-' {
- break
- }
- }
- return out[a : b+1]
-}
diff --git a/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/node.go b/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/node.go
deleted file mode 100644
index d820b83..0000000
--- a/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/node.go
+++ /dev/null
@@ -1,355 +0,0 @@
-//nolint:gocritic,unused // ignore blackfriday
-package blackfriday
-
-import (
- "bytes"
- "fmt"
-)
-
-// NodeType specifies a type of a single node of a syntax tree. Usually one
-// node (and its type) corresponds to a single markdown feature, e.g. emphasis
-// or code block.
-type NodeType int
-
-// Constants for identifying different types of nodes. See NodeType.
-const (
- Document NodeType = iota
- BlockQuote
- List
- Item
- Paragraph
- Heading
- HorizontalRule
- Emph
- Strong
- Del
- Link
- Image
- Text
- HTMLBlock
- CodeBlock
- Softbreak
- Hardbreak
- Code
- HTMLSpan
- Table
- TableCell
- TableHead
- TableBody
- TableRow
-)
-
-var nodeTypeNames = []string{
- Document: "Document",
- BlockQuote: "BlockQuote",
- List: "List",
- Item: "Item",
- Paragraph: "Paragraph",
- Heading: "Heading",
- HorizontalRule: "HorizontalRule",
- Emph: "Emph",
- Strong: "Strong",
- Del: "Del",
- Link: "Link",
- Image: "Image",
- Text: "Text",
- HTMLBlock: "HTMLBlock",
- CodeBlock: "CodeBlock",
- Softbreak: "Softbreak",
- Hardbreak: "Hardbreak",
- Code: "Code",
- HTMLSpan: "HTMLSpan",
- Table: "Table",
- TableCell: "TableCell",
- TableHead: "TableHead",
- TableBody: "TableBody",
- TableRow: "TableRow",
-}
-
-func (t NodeType) String() string {
- return nodeTypeNames[t]
-}
-
-// ListData contains fields relevant to a List and Item node type.
-type ListData struct {
- ListFlags ListType
- Tight bool // Skip <p>s around list item data if true
- BulletChar byte // '*', '+' or '-' in bullet lists
- Delimiter byte // '.' or ')' after the number in ordered lists
- RefLink []byte // If not nil, turns this list item into a footnote item and triggers different rendering
- IsFootnotesList bool // This is a list of footnotes
-}
-
-// LinkData contains fields relevant to a Link node type.
-type LinkData struct {
- Destination []byte // Destination is what goes into a href
- Title []byte // Title is the tooltip thing that goes in a title attribute
- NoteID int // NoteID contains a serial number of a footnote, zero if it's not a footnote
- Footnote *Node // If it's a footnote, this is a direct link to the footnote Node. Otherwise nil.
-}
-
-// CodeBlockData contains fields relevant to a CodeBlock node type.
-type CodeBlockData struct {
- IsFenced bool // Specifies whether it's a fenced code block or an indented one
- Info []byte // This holds the info string
- FenceChar byte
- FenceLength int
- FenceOffset int
-}
-
-// TableCellData contains fields relevant to a TableCell node type.
-type TableCellData struct {
- IsHeader bool // This tells if it's under the header row
- Align CellAlignFlags // This holds the value for align attribute
-}
-
-// HeadingData contains fields relevant to a Heading node type.
-type HeadingData struct {
- Level int // This holds the heading level number
- HeadingID string // This might hold heading ID, if present
- IsTitleblock bool // Specifies whether it's a title block
-}
-
-// Node is a single element in the abstract syntax tree of the parsed document.
-// It holds connections to the structurally neighboring nodes and, for certain
-// types of nodes, additional information that might be needed when rendering.
-type Node struct {
- Type NodeType // Determines the type of the node
- Parent *Node // Points to the parent
- FirstChild *Node // Points to the first child, if any
- LastChild *Node // Points to the last child, if any
- Prev *Node // Previous sibling; nil if it's the first child
- Next *Node // Next sibling; nil if it's the last child
-
- Literal []byte // Text contents of the leaf nodes
-
- HeadingData // Populated if Type is Heading
- ListData // Populated if Type is List
- CodeBlockData // Populated if Type is CodeBlock
- LinkData // Populated if Type is Link
- TableCellData // Populated if Type is TableCell
-
- content []byte // Markdown content of the block nodes
- open bool // Specifies an open block node that has not been finished to process yet
-}
-
-// NewNode allocates a node of a specified type.
-func NewNode(typ NodeType) *Node {
- return &Node{
- Type: typ,
- open: true,
- }
-}
-
-func (n *Node) String() string {
- ellipsis := ""
- snippet := n.Literal
- if len(snippet) > 16 {
- snippet = snippet[:16]
- ellipsis = "..."
- }
- return fmt.Sprintf("%s: '%s%s'", n.Type, snippet, ellipsis)
-}
-
-// Unlink removes node 'n' from the tree.
-// It panics if the node is nil.
-func (n *Node) Unlink() {
- if n.Prev != nil {
- n.Prev.Next = n.Next
- } else if n.Parent != nil {
- n.Parent.FirstChild = n.Next
- }
- if n.Next != nil {
- n.Next.Prev = n.Prev
- } else if n.Parent != nil {
- n.Parent.LastChild = n.Prev
- }
- n.Parent = nil
- n.Next = nil
- n.Prev = nil
-}
-
-// AppendChild adds a node 'child' as a child of 'n'.
-// It panics if either node is nil.
-func (n *Node) AppendChild(child *Node) {
- child.Unlink()
- child.Parent = n
- if n.LastChild != nil {
- n.LastChild.Next = child
- child.Prev = n.LastChild
- n.LastChild = child
- } else {
- n.FirstChild = child
- n.LastChild = child
- }
-}
-
-// InsertBefore inserts 'sibling' immediately before 'n'.
-// It panics if either node is nil.
-func (n *Node) InsertBefore(sibling *Node) {
- sibling.Unlink()
- sibling.Prev = n.Prev
- if sibling.Prev != nil {
- sibling.Prev.Next = sibling
- }
- sibling.Next = n
- n.Prev = sibling
- sibling.Parent = n.Parent
- if sibling.Prev == nil {
- sibling.Parent.FirstChild = sibling
- }
-}
-
-func (n *Node) isContainer() bool {
- switch n.Type {
- case Document:
- fallthrough
- case BlockQuote:
- fallthrough
- case List:
- fallthrough
- case Item:
- fallthrough
- case Paragraph:
- fallthrough
- case Heading:
- fallthrough
- case Emph:
- fallthrough
- case Strong:
- fallthrough
- case Del:
- fallthrough
- case Link:
- fallthrough
- case Image:
- fallthrough
- case Table:
- fallthrough
- case TableHead:
- fallthrough
- case TableBody:
- fallthrough
- case TableRow:
- fallthrough
- case TableCell:
- return true
- default:
- return false
- }
-}
-
-func (n *Node) canContain(t NodeType) bool {
- if n.Type == List {
- return t == Item
- }
- if n.Type == Document || n.Type == BlockQuote || n.Type == Item {
- return t != Item
- }
- if n.Type == Table {
- return t == TableHead || t == TableBody
- }
- if n.Type == TableHead || n.Type == TableBody {
- return t == TableRow
- }
- if n.Type == TableRow {
- return t == TableCell
- }
- return false
-}
-
-// WalkStatus allows NodeVisitor to have some control over the tree traversal.
-// It is returned from NodeVisitor and different values allow Node.Walk to
-// decide which node to go to next.
-type WalkStatus int
-
-const (
- // GoToNext is the default traversal of every node.
- GoToNext WalkStatus = iota
- // SkipChildren tells walker to skip all children of current node.
- SkipChildren
- // Terminate tells walker to terminate the traversal.
- Terminate
-)
-
-// NodeVisitor is a callback to be called when traversing the syntax tree.
-// Called twice for every node: once with entering=true when the branch is
-// first visited, then with entering=false after all the children are done.
-type NodeVisitor func(node *Node, entering bool) WalkStatus
-
-// Walk is a convenience method that instantiates a walker and starts a
-// traversal of subtree rooted at n.
-func (n *Node) Walk(visitor NodeVisitor) {
- w := newNodeWalker(n)
- for w.current != nil {
- status := visitor(w.current, w.entering)
- switch status {
- case GoToNext:
- w.next()
- case SkipChildren:
- w.entering = false
- w.next()
- case Terminate:
- return
- }
- }
-}
-
-type nodeWalker struct {
- current *Node
- root *Node
- entering bool
-}
-
-func newNodeWalker(root *Node) *nodeWalker {
- return &nodeWalker{
- current: root,
- root: root,
- entering: true,
- }
-}
-
-func (nw *nodeWalker) next() {
- if (!nw.current.isContainer() || !nw.entering) && nw.current == nw.root {
- nw.current = nil
- return
- }
- if nw.entering && nw.current.isContainer() {
- if nw.current.FirstChild != nil {
- nw.current = nw.current.FirstChild
- nw.entering = true
- } else {
- nw.entering = false
- }
- } else if nw.current.Next == nil {
- nw.current = nw.current.Parent
- nw.entering = false
- } else {
- nw.current = nw.current.Next
- nw.entering = true
- }
-}
-
-func dump(ast *Node) {
- fmt.Println(dumpString(ast))
-}
-
-func dumpR(ast *Node, depth int) string {
- if ast == nil {
- return ""
- }
- indent := bytes.Repeat([]byte("\t"), depth)
- content := ast.Literal
- if content == nil {
- content = ast.content
- }
- result := fmt.Sprintf("%s%s(%q)\n", indent, ast.Type, content)
- for n := ast.FirstChild; n != nil; n = n.Next {
- result += dumpR(n, depth+1)
- }
- return result
-}
-
-func dumpString(ast *Node) string {
- return dumpR(ast, 0)
-}
diff --git a/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/smartypants.go b/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/smartypants.go
deleted file mode 100644
index e5f9e19..0000000
--- a/vendor/github.com/smallstep/cli-utils/pkg/blackfriday/smartypants.go
+++ /dev/null
@@ -1,458 +0,0 @@
-//
-// Blackfriday Markdown Processor
-// Available at http://github.com/russross/blackfriday
-//
-// Copyright © 2011 Russ Ross <russ@russross.com>.
-// Distributed under the Simplified BSD License.
-// See README.md for details.
-//
-
-//
-//
-// SmartyPants rendering
-//
-//
-
-//nolint:gocritic,revive // ignore blackfriday
-package blackfriday
-
-import (
- "bytes"
- "io"
-)
-
-// SPRenderer is a struct containing state of a Smartypants renderer.
-type SPRenderer struct {
- inSingleQuote bool
- inDoubleQuote bool
- callbacks [256]smartCallback
-}
-
-func wordBoundary(c byte) bool {
- return c == 0 || isspace(c) || ispunct(c)
-}
-
-func tolower(c byte) byte {
- if c >= 'A' && c <= 'Z' {
- return c - 'A' + 'a'
- }
- return c
-}
-
-func isdigit(c byte) bool {
- return c >= '0' && c <= '9'
-}
-
-func smartQuoteHelper(out *bytes.Buffer, previousChar byte, nextChar byte, quote byte, isOpen *bool, addNBSP bool) bool {
- // edge of the buffer is likely to be a tag that we don't get to see,
- // so we treat it like text sometimes
-
- // enumerate all sixteen possibilities for (previousChar, nextChar)
- // each can be one of {0, space, punct, other}
- switch {
- case previousChar == 0 && nextChar == 0:
- // context is not any help here, so toggle
- *isOpen = !*isOpen
- case isspace(previousChar) && nextChar == 0:
- // [ "] might be [ "<code>foo...]
- *isOpen = true
- case ispunct(previousChar) && nextChar == 0:
- // [!"] hmm... could be [Run!"] or [("<code>...]
- *isOpen = false
- case /* isnormal(previousChar) && */ nextChar == 0:
- // [a"] is probably a close
- *isOpen = false
- case previousChar == 0 && isspace(nextChar):
- // [" ] might be [...foo</code>" ]
- *isOpen = false
- case isspace(previousChar) && isspace(nextChar):
- // [ " ] context is not any help here, so toggle
- *isOpen = !*isOpen
- case ispunct(previousChar) && isspace(nextChar):
- // [!" ] is probably a close
- *isOpen = false
- case /* isnormal(previousChar) && */ isspace(nextChar):
- // [a" ] this is one of the easy cases
- *isOpen = false
- case previousChar == 0 && ispunct(nextChar):
- // ["!] hmm... could be ["$1.95] or [</code>"!...]
- *isOpen = false
- case isspace(previousChar) && ispunct(nextChar):
- // [ "!] looks more like [ "$1.95]
- *isOpen = true
- case ispunct(previousChar) && ispunct(nextChar):
- // [!"!] context is not any help here, so toggle
- *isOpen = !*isOpen
- case /* isnormal(previousChar) && */ ispunct(nextChar):
- // [a"!] is probably a close
- *isOpen = false
- case previousChar == 0 /* && isnormal(nextChar) */ :
- // ["a] is probably an open
- *isOpen = true
- case isspace(previousChar) /* && isnormal(nextChar) */ :
- // [ "a] this is one of the easy cases
- *isOpen = true
- case ispunct(previousChar) /* && isnormal(nextChar) */ :
- // [!"a] is probably an open
- *isOpen = true
- default:
- // [a'b] maybe a contraction?
- *isOpen = false
- }
-
- // Note that with the limited lookahead, this non-breaking
- // space will also be appended to single double quotes.
- if addNBSP && !*isOpen {
- out.WriteString("&nbsp;")
- }
-
- out.WriteByte('&')
- if *isOpen {
- out.WriteByte('l')
- } else {
- out.WriteByte('r')
- }
- out.WriteByte(quote)
- out.WriteString("quo;")
-
- if addNBSP && *isOpen {
- out.WriteString("&nbsp;")
- }
-
- return true
-}
-
-func (r *SPRenderer) smartSingleQuote(out *bytes.Buffer, previousChar byte, text []byte) int {
- if len(text) >= 2 {
- t1 := tolower(text[1])
-
- if t1 == '\'' {
- nextChar := byte(0)
- if len(text) >= 3 {
- nextChar = text[2]
- }
- if smartQuoteHelper(out, previousChar, nextChar, 'd', &r.inDoubleQuote, false) {
- return 1
- }
- }
-
- if (t1 == 's' || t1 == 't' || t1 == 'm' || t1 == 'd') && (len(text) < 3 || wordBoundary(text[2])) {
- out.WriteString("&rsquo;")
- return 0
- }
-
- if len(text) >= 3 {
- t2 := tolower(text[2])
-
- if ((t1 == 'r' && t2 == 'e') || (t1 == 'l' && t2 == 'l') || (t1 == 'v' && t2 == 'e')) &&
- (len(text) < 4 || wordBoundary(text[3])) {
- out.WriteString("&rsquo;")
- return 0
- }
- }
- }
-
- nextChar := byte(0)
- if len(text) > 1 {
- nextChar = text[1]
- }
- if smartQuoteHelper(out, previousChar, nextChar, 's', &r.inSingleQuote, false) {
- return 0
- }
-
- out.WriteByte(text[0])
- return 0
-}
-
-func (r *SPRenderer) smartParens(out *bytes.Buffer, previousChar byte, text []byte) int {
- if len(text) >= 3 {
- t1 := tolower(text[1])
- t2 := tolower(text[2])
-
- if t1 == 'c' && t2 == ')' {
- out.WriteString("&copy;")
- return 2
- }
-
- if t1 == 'r' && t2 == ')' {
- out.WriteString("&reg;")
- return 2
- }
-
- if len(text) >= 4 && t1 == 't' && t2 == 'm' && text[3] == ')' {
- out.WriteString("&trade;")
- return 3
- }
- }
-
- out.WriteByte(text[0])
- return 0
-}
-
-func (r *SPRenderer) smartDash(out *bytes.Buffer, previousChar byte, text []byte) int {
- if len(text) >= 2 {
- if text[1] == '-' {
- out.WriteString("&mdash;")
- return 1
- }
-
- if wordBoundary(previousChar) && wordBoundary(text[1]) {
- out.WriteString("&ndash;")
- return 0
- }
- }
-
- out.WriteByte(text[0])
- return 0
-}
-
-func (r *SPRenderer) smartDashLatex(out *bytes.Buffer, previousChar byte, text []byte) int {
- if len(text) >= 3 && text[1] == '-' && text[2] == '-' {
- out.WriteString("&mdash;")
- return 2
- }
- if len(text) >= 2 && text[1] == '-' {
- out.WriteString("&ndash;")
- return 1
- }
-
- out.WriteByte(text[0])
- return 0
-}
-
-func (r *SPRenderer) smartAmpVariant(out *bytes.Buffer, previousChar byte, text []byte, quote byte, addNBSP bool) int {
- if bytes.HasPrefix(text, []byte("&quot;")) {
- nextChar := byte(0)
- if len(text) >= 7 {
- nextChar = text[6]
- }
- if smartQuoteHelper(out, previousChar, nextChar, quote, &r.inDoubleQuote, addNBSP) {
- return 5
- }
- }
-
- if bytes.HasPrefix(text, []byte("&#0;")) {
- return 3
- }
-
- out.WriteByte('&')
- return 0
-}
-
-func (r *SPRenderer) smartAmp(angledQuotes, addNBSP bool) func(*bytes.Buffer, byte, []byte) int {
- var quote byte = 'd'
- if angledQuotes {
- quote = 'a'
- }
-
- return func(out *bytes.Buffer, previousChar byte, text []byte) int {
- return r.smartAmpVariant(out, previousChar, text, quote, addNBSP)
- }
-}
-
-func (r *SPRenderer) smartPeriod(out *bytes.Buffer, previousChar byte, text []byte) int {
- if len(text) >= 3 && text[1] == '.' && text[2] == '.' {
- out.WriteString("&hellip;")
- return 2
- }
-
- if len(text) >= 5 && text[1] == ' ' && text[2] == '.' && text[3] == ' ' && text[4] == '.' {
- out.WriteString("&hellip;")
- return 4
- }
-
- out.WriteByte(text[0])
- return 0
-}
-
-func (r *SPRenderer) smartBacktick(out *bytes.Buffer, previousChar byte, text []byte) int {
- if len(text) >= 2 && text[1] == '`' {
- nextChar := byte(0)
- if len(text) >= 3 {
- nextChar = text[2]
- }
- if smartQuoteHelper(out, previousChar, nextChar, 'd', &r.inDoubleQuote, false) {
- return 1
- }
- }
-
- out.WriteByte(text[0])
- return 0
-}
-
-func (r *SPRenderer) smartNumberGeneric(out *bytes.Buffer, previousChar byte, text []byte) int {
- if wordBoundary(previousChar) && previousChar != '/' && len(text) >= 3 {
- // is it of the form digits/digits(word boundary)?, i.e., \d+/\d+\b
- // note: check for regular slash (/) or fraction slash (⁄, 0x2044, or 0xe2 81 84 in utf-8)
- // and avoid changing dates like 1/23/2005 into fractions.
- numEnd := 0
- for len(text) > numEnd && isdigit(text[numEnd]) {
- numEnd++
- }
- if numEnd == 0 {
- out.WriteByte(text[0])
- return 0
- }
- denStart := numEnd + 1
- if len(text) > numEnd+3 && text[numEnd] == 0xe2 && text[numEnd+1] == 0x81 && text[numEnd+2] == 0x84 {
- denStart = numEnd + 3
- } else if len(text) < numEnd+2 || text[numEnd] != '/' {
- out.WriteByte(text[0])
- return 0
- }
- denEnd := denStart
- for len(text) > denEnd && isdigit(text[denEnd]) {
- denEnd++
- }
- if denEnd == denStart {
- out.WriteByte(text[0])
- return 0
- }
- if len(text) == denEnd || wordBoundary(text[denEnd]) && text[denEnd] != '/' {
- out.WriteString("<sup>")
- out.Write(text[:numEnd])
- out.WriteString("</sup>&frasl;<sub>")
- out.Write(text[denStart:denEnd])
- out.WriteString("</sub>")
- return denEnd - 1
- }
- }
-
- out.WriteByte(text[0])
- return 0
-}
-
-func (r *SPRenderer) smartNumber(out *bytes.Buffer, previousChar byte, text []byte) int {
- if wordBoundary(previousChar) && previousChar != '/' && len(text) >= 3 {
- if text[0] == '1' && text[1] == '/' && text[2] == '2' {
- if len(text) < 4 || wordBoundary(text[3]) && text[3] != '/' {
- out.WriteString("&frac12;")
- return 2
- }
- }
-
- if text[0] == '1' && text[1] == '/' && text[2] == '4' {
- if len(text) < 4 || wordBoundary(text[3]) && text[3] != '/' || (len(text) >= 5 && tolower(text[3]) == 't' && tolower(text[4]) == 'h') {
- out.WriteString("&frac14;")
- return 2
- }
- }
-
- if text[0] == '3' && text[1] == '/' && text[2] == '4' {
- if len(text) < 4 || wordBoundary(text[3]) && text[3] != '/' || (len(text) >= 6 && tolower(text[3]) == 't' && tolower(text[4]) == 'h' && tolower(text[5]) == 's') {
- out.WriteString("&frac34;")
- return 2
- }
- }
- }
-
- out.WriteByte(text[0])
- return 0
-}
-
-func (r *SPRenderer) smartDoubleQuoteVariant(out *bytes.Buffer, previousChar byte, text []byte, quote byte) int {
- nextChar := byte(0)
- if len(text) > 1 {
- nextChar = text[1]
- }
- if !smartQuoteHelper(out, previousChar, nextChar, quote, &r.inDoubleQuote, false) {
- out.WriteString("&quot;")
- }
-
- return 0
-}
-
-func (r *SPRenderer) smartDoubleQuote(out *bytes.Buffer, previousChar byte, text []byte) int {
- return r.smartDoubleQuoteVariant(out, previousChar, text, 'd')
-}
-
-func (r *SPRenderer) smartAngledDoubleQuote(out *bytes.Buffer, previousChar byte, text []byte) int {
- return r.smartDoubleQuoteVariant(out, previousChar, text, 'a')
-}
-
-func (r *SPRenderer) smartLeftAngle(out *bytes.Buffer, previousChar byte, text []byte) int {
- i := 0
-
- for i < len(text) && text[i] != '>' {
- i++
- }
-
- out.Write(text[:i+1])
- return i
-}
-
-type smartCallback func(out *bytes.Buffer, previousChar byte, text []byte) int
-
-// NewSmartypantsRenderer constructs a Smartypants renderer object.
-func NewSmartypantsRenderer(flags HTMLFlags) *SPRenderer {
- var (
- r SPRenderer
-
- smartAmpAngled = r.smartAmp(true, false)
- smartAmpAngledNBSP = r.smartAmp(true, true)
- smartAmpRegular = r.smartAmp(false, false)
- smartAmpRegularNBSP = r.smartAmp(false, true)
-
- addNBSP = flags&SmartypantsQuotesNBSP != 0
- )
-
- if flags&SmartypantsAngledQuotes == 0 {
- r.callbacks['"'] = r.smartDoubleQuote
- if !addNBSP {
- r.callbacks['&'] = smartAmpRegular
- } else {
- r.callbacks['&'] = smartAmpRegularNBSP
- }
- } else {
- r.callbacks['"'] = r.smartAngledDoubleQuote
- if !addNBSP {
- r.callbacks['&'] = smartAmpAngled
- } else {
- r.callbacks['&'] = smartAmpAngledNBSP
- }
- }
- r.callbacks['\''] = r.smartSingleQuote
- r.callbacks['('] = r.smartParens
- if flags&SmartypantsDashes != 0 {
- if flags&SmartypantsLatexDashes == 0 {
- r.callbacks['-'] = r.smartDash
- } else {
- r.callbacks['-'] = r.smartDashLatex
- }
- }
- r.callbacks['.'] = r.smartPeriod
- if flags&SmartypantsFractions == 0 {
- r.callbacks['1'] = r.smartNumber
- r.callbacks['3'] = r.smartNumber
- } else {
- for ch := '1'; ch <= '9'; ch++ {
- r.callbacks[ch] = r.smartNumberGeneric
- }
- }
- r.callbacks['<'] = r.smartLeftAngle
- r.callbacks['`'] = r.smartBacktick
- return &r
-}
-
-// Process is the entry point of the Smartypants renderer.
-func (r *SPRenderer) Process(w io.Writer, text []byte) {
- mark := 0
- for i := 0; i < len(text); i++ {
- if action := r.callbacks[text[i]]; action != nil {
- if i > mark {
- w.Write(text[mark:i])
- }
- previousChar := byte(0)
- if i > 0 {
- previousChar = text[i-1]
- }
- var tmp bytes.Buffer
- i += action(&tmp, previousChar, text[i:])
- w.Write(tmp.Bytes())
- mark = i + 1
- }
- }
- if mark < len(text) {
- w.Write(text[mark:])
- }
-}
diff --git a/vendor/github.com/smallstep/cli-utils/step/config.go b/vendor/github.com/smallstep/cli-utils/step/config.go
deleted file mode 100644
index 269f21a..0000000
--- a/vendor/github.com/smallstep/cli-utils/step/config.go
+++ /dev/null
@@ -1,220 +0,0 @@
-package step
-
-import (
- "fmt"
- "os"
- "os/user"
- "path/filepath"
- "runtime"
- "strings"
- "sync"
- "time"
-)
-
-// PathEnv defines the name of the environment variable that can overwrite
-// the default configuration path.
-const PathEnv = "STEPPATH"
-
-// HomeEnv defines the name of the environment variable that can overwrite the
-// default home directory.
-const HomeEnv = "HOME"
-
-var (
- // version and buildTime are filled in during build by the Makefile
- name = "Smallstep CLI"
- buildTime = "N/A"
- version = "N/A"
-)
-
-var cache struct {
- sync.Once
- err error
- stepBasePath string // stepBasePath will be populated in init() with the proper STEPPATH.
- homePath string // homePath will be populated in init() with the proper HOME.
-}
-
-// Init initializes the step environment.
-//
-// A program calling this function should fail because the step variables would
-// be undefined.
-func Init() error {
- if err := initStepPath(); err != nil {
- return err
- }
- return Contexts().Init()
-}
-
-func initStepPath() error {
- cache.Do(func() {
- // Get home path from environment or from the user object.
- homePath := os.Getenv(HomeEnv)
- if homePath == "" {
- usr, err := user.Current()
- if err == nil && usr.HomeDir != "" {
- homePath = usr.HomeDir
- } else {
- cache.err = fmt.Errorf("error obtaining home directory, please define environment variable %s", HomeEnv)
- return
- }
- }
-
- // Get step path from environment or relative to home.
- stepBasePath := os.Getenv(PathEnv)
- if stepBasePath == "" {
- stepBasePath = filepath.Join(homePath, ".step")
- }
-
- // cleanup and add paths to cache
- cache.homePath = filepath.Clean(homePath)
- cache.stepBasePath = filepath.Clean(stepBasePath)
- })
-
- return cache.err
-}
-
-// Home returns the user home directory using the environment variable HOME or
-// the os/user package.
-func Home() string {
- _ = initStepPath()
- return cache.homePath
-}
-
-// BasePath returns the base path for the step configuration directory.
-func BasePath() string {
- _ = initStepPath()
- return cache.stepBasePath
-}
-
-// Path returns the path for the step configuration directory.
-//
-// 1. If the base step path has a current context configured, then this method
-// returns the path to the authority configured in the context.
-// 2. If the base step path does not have a current context configured this
-// method returns the value defined by the environment variable STEPPATH, OR
-// 3. If no environment variable is set, this method returns `$HOME/.step`.
-func Path() string {
- c := Contexts().GetCurrent()
- if c == nil {
- return BasePath()
- }
- return filepath.Join(BasePath(), "authorities", c.Authority)
-}
-
-// ProfilePath returns the path for the currently selected profile path.
-//
-// 1. If the base step path has a current context configured, then this method
-// returns the path to the profile configured in the context.
-// 2. If the base step path does not have a current context configured this
-// method returns the value defined by the environment variable STEPPATH, OR
-// 3. If no environment variable is set, this method returns `$HOME/.step`.
-func ProfilePath() string {
- c := Contexts().GetCurrent()
- if c == nil {
- return BasePath()
- }
- return filepath.Join(BasePath(), "profiles", c.Profile)
-}
-
-// IdentityPath returns the location of the identity directory.
-func IdentityPath() string {
- return filepath.Join(Path(), "identity")
-}
-
-// IdentityFile returns the location of the identity file.
-func IdentityFile() string {
- return filepath.Join(Path(), "config", "identity.json")
-}
-
-// DefaultsFile returns the location of the defaults file at the base of the
-// authority path.
-func DefaultsFile() string {
- return filepath.Join(Path(), "config", "defaults.json")
-}
-
-// ProfileDefaultsFile returns the location of the defaults file at the base
-// of the profile path.
-func ProfileDefaultsFile() string {
- return filepath.Join(ProfilePath(), "config", "defaults.json")
-}
-
-// ConfigPath returns the location of the $(step path)/config directory.
-func ConfigPath() string {
- return filepath.Join(Path(), "config")
-}
-
-// ProfileConfigPath returns the location of the $(step path --profile)/config directory.
-func ProfileConfigPath() string {
- return filepath.Join(ProfilePath(), "config")
-}
-
-// CaConfigFile returns the location of the ca.json file -- configuration for
-// connecting to the CA.
-func CaConfigFile() string {
- return filepath.Join(Path(), "config", "ca.json")
-}
-
-// ContextsFile returns the location of the config file.
-func ContextsFile() string {
- return filepath.Join(BasePath(), "contexts.json")
-}
-
-// CurrentContextFile returns the path to the file containing the current context.
-func CurrentContextFile() string {
- return filepath.Join(BasePath(), "current-context.json")
-}
-
-// Abs returns the given path relative to the STEPPATH if it's not an
-// absolute path, relative to the home directory using the special string "~/",
-// or relative to the working directory using "./"
-//
-// Relative paths like 'certs/root_ca.crt' will be converted to
-// '$STEPPATH/certs/root_ca.crt', but paths like './certs/root_ca.crt' will be
-// relative to the current directory. Home relative paths like
-// ~/certs/root_ca.crt will be converted to '$HOME/certs/root_ca.crt'. And
-// absolute paths like '/certs/root_ca.crt' will remain the same.
-func Abs(path string) string {
- if filepath.IsAbs(path) {
- return path
- }
- // Windows accept both \ and /
- slashed := filepath.ToSlash(path)
- switch {
- case strings.HasPrefix(slashed, "~/"):
- return filepath.Join(Home(), path[2:])
- case strings.HasPrefix(slashed, "./"), strings.HasPrefix(slashed, "../"):
- if abs, err := filepath.Abs(path); err == nil {
- return abs
- }
- return path
- default:
- return filepath.Join(Path(), path)
- }
-}
-
-// Set updates the name, version, and build time
-func Set(n, v, t string) {
- name = n
- version = v
- buildTime = t
-}
-
-// Version returns the current version of the binary
-func Version() string {
- out := version
- if version == "N/A" {
- out = "0000000-dev"
- }
-
- return fmt.Sprintf("%s/%s (%s/%s)",
- name, out, runtime.GOOS, runtime.GOARCH)
-}
-
-// ReleaseDate returns the time of when the binary was built
-func ReleaseDate() string {
- out := buildTime
- if buildTime == "N/A" {
- out = time.Now().UTC().Format("2006-01-02 15:04 MST")
- }
-
- return out
-}
diff --git a/vendor/github.com/smallstep/cli-utils/step/context.go b/vendor/github.com/smallstep/cli-utils/step/context.go
deleted file mode 100644
index c4f7e4e..0000000
--- a/vendor/github.com/smallstep/cli-utils/step/context.go
+++ /dev/null
@@ -1,565 +0,0 @@
-package step
-
-import (
- "encoding/json"
- "fmt"
- "os"
- "path/filepath"
- "reflect"
- "sort"
- "strings"
-
- "github.com/pkg/errors"
- "github.com/urfave/cli"
-
- "github.com/smallstep/cli-utils/errs"
- "github.com/smallstep/cli-utils/ui"
-)
-
-// IgnoreEnvVar is a value added to a flag EnvVar to avoid the use of
-// environment variables or configuration files.
-const IgnoreEnvVar = "STEP_IGNORE_ENV_VAR"
-
-// Context represents a Step Path configuration context. A context is the
-// combination of a profile and an authority.
-type Context struct {
- Name string `json:"-"`
- Profile string `json:"profile"`
- Authority string `json:"authority"`
- config map[string]interface{}
-}
-
-// Validate validates a context and returns an error if invalid.
-func (c *Context) Validate() error {
- suffix := "; check your $STEPPATH/contexts.json file"
- if c == nil {
- return errors.Errorf("context cannot be nil%s", suffix)
- }
- if c.Authority == "" {
- return errors.Errorf("context cannot have an empty authority value%s", suffix)
- }
- if c.Profile == "" {
- return errors.Errorf("context cannot have an empty profile value%s", suffix)
- }
- return nil
-}
-
-// Path return the base path relative to the context.
-func (c *Context) Path() string {
- return filepath.Join(BasePath(), "authorities", c.Authority)
-}
-
-// ProfilePath return the profile base path relative to the context.
-func (c *Context) ProfilePath() string {
- return filepath.Join(BasePath(), "profiles", c.Profile)
-}
-
-// DefaultsFile returns the location of the defaults file for the context.
-func (c *Context) DefaultsFile() string {
- return filepath.Join(c.Path(), "config", "defaults.json")
-}
-
-// ProfileDefaultsFile returns the location of the defaults file at the base
-// of the profile path.
-func (c *Context) ProfileDefaultsFile() string {
- return filepath.Join(c.ProfilePath(), "config", "defaults.json")
-}
-
-// Load loads the configuration for the given context.
-func (c *Context) Load() error {
- c.config = map[string]interface{}{}
- for _, f := range []string{c.DefaultsFile(), c.ProfileDefaultsFile()} {
- b, err := os.ReadFile(f)
- if os.IsNotExist(err) {
- continue
- } else if err != nil {
- return errs.FileError(err, f)
- }
-
- values := make(map[string]interface{})
- if err := json.Unmarshal(b, &values); err != nil {
- return errors.Wrapf(err, "error parsing %s", f)
- }
-
- for k, v := range values {
- c.config[k] = v
- }
- }
-
- attributesBannedFromConfig := []string{
- "context",
- "profile",
- "authority",
- }
- for _, attr := range attributesBannedFromConfig {
- if _, ok := c.config[attr]; ok {
- ui.Printf("cannot set '%s' attribute in config files\n", attr)
- delete(c.config, attr)
- }
- }
-
- return nil
-}
-
-// ContextMap represents the map of available Contexts that is stored
-// at the base of the Step Path.
-type ContextMap map[string]*Context
-
-type storedCurrent struct {
- Context string `json:"context"`
-}
-
-// CtxState is the type that manages context state for the cli.
-type CtxState struct {
- current *Context
- contexts ContextMap
- config map[string]interface{}
-}
-
-var ctxState = &CtxState{}
-
-// Init initializes the context map and current context state.
-func (cs *CtxState) Init() error {
- if err := cs.initMap(); err != nil {
- return err
- }
- if err := cs.initCurrent(); err != nil {
- return err
- }
- return cs.load()
-}
-
-func (cs *CtxState) initMap() error {
- contextsFile := ContextsFile()
- b, err := os.ReadFile(contextsFile)
- if os.IsNotExist(err) {
- return nil
- } else if err != nil {
- return errs.FileError(err, contextsFile)
- }
- cs.contexts = ContextMap{}
- if err := json.Unmarshal(b, &cs.contexts); err != nil {
- return errors.Wrap(err, "error unmarshaling context map")
- }
- for k, ctx := range cs.contexts {
- if err := ctx.Validate(); err != nil {
- return errors.Wrapf(err, "error in context '%s'", k)
- }
- ctx.Name = k
- }
- return nil
-}
-
-func (cs *CtxState) initCurrent() error {
- currentCtxFile := CurrentContextFile()
- b, err := os.ReadFile(currentCtxFile)
- if os.IsNotExist(err) {
- return nil
- } else if err != nil {
- return errs.FileError(err, currentCtxFile)
- }
-
- var sc storedCurrent
- if err := json.Unmarshal(b, &sc); err != nil {
- return errors.Wrap(err, "error unmarshaling current context")
- }
-
- return cs.SetCurrent(sc.Context)
-}
-
-func (cs *CtxState) load() error {
- if cs.Enabled() && cs.GetCurrent() != nil {
- if err := cs.GetCurrent().Load(); err != nil {
- return fmt.Errorf("failed loading current context configuration: %w", err)
- }
-
- return nil
- }
-
- if err := cs.LoadVintage(""); err != nil {
- return fmt.Errorf("failed loading context configuration: %w", err)
- }
-
- return nil
-}
-
-// LoadVintage loads context configuration from the vintage (non-context) path.
-func (cs *CtxState) LoadVintage(f string) error {
- if f == "" {
- f = DefaultsFile()
- }
-
- b, err := os.ReadFile(f)
- if os.IsNotExist(err) {
- return nil
- } else if err != nil {
- return errs.FileError(err, f)
- }
-
- cs.config = make(map[string]interface{})
- if err := json.Unmarshal(b, &cs.config); err != nil {
- return errors.Wrapf(err, "error parsing %s", f)
- }
- return nil
-}
-
-// GetConfig returns the current context configuration.
-func (cs *CtxState) GetConfig() (map[string]interface{}, error) {
- if cs.Enabled() {
- cur := cs.GetCurrent()
- if cur == nil {
- return nil, errors.New("cannot get context configuration; no current context set")
- }
- return cur.config, nil
- }
- return cs.config, nil
-}
-
-// SetCurrent sets the current context or returns an error if a context
-// with the given name does not exist.
-func (cs *CtxState) SetCurrent(name string) error {
- var ok bool
- cs.current, ok = cs.contexts[name]
- if !ok {
- return errors.Errorf("could not load context '%s'", name)
- }
- if len(cs.current.config) == 0 {
- if err := cs.current.Load(); err != nil {
- return err
- }
- }
- return nil
-}
-
-type contextSelect struct {
- Name string
- Context *Context
-}
-
-// PromptContext gets user input to select a context.
-func (cs *CtxState) PromptContext() error {
- var items []*contextSelect
- for _, context := range cs.List() {
- items = append(items, &contextSelect{
- Name: context.Name,
- Context: context,
- })
- }
-
- var ctxStr string
- if len(items) == 1 {
- if err := ui.PrintSelected("Context", items[0].Name); err != nil {
- return err
- }
- ctxStr = items[0].Name
- } else {
- i, _, err := ui.Select("Select a context for 'step':", items,
- ui.WithSelectTemplates(ui.NamedSelectTemplates("Context")))
- if err != nil {
- return err
- }
- ctxStr = items[i].Name
- }
- if err := cs.SetCurrent(ctxStr); err != nil {
- return err
- }
- return cs.SaveCurrent(ctxStr)
-}
-
-// Enabled returns true if one of the following is true:
-// - there is a current context configured
-// - the context map is (list of available contexts) is not empty.
-func (cs *CtxState) Enabled() bool {
- return cs.current != nil || len(cs.contexts) > 0
-}
-
-// Contexts returns an object that enables context management.
-func Contexts() *CtxState {
- return ctxState
-}
-
-// Add adds a new context to the context map. If current context is not
-// set then store the new context as the current context for future commands.
-func (cs *CtxState) Add(ctx *Context) error {
- if err := ctx.Validate(); err != nil {
- return errors.Wrapf(err, "error adding context")
- }
- if cs.contexts == nil {
- cs.contexts = map[string]*Context{ctx.Name: ctx}
- } else {
- cs.contexts[ctx.Name] = ctx
- }
-
- b, err := json.MarshalIndent(cs.contexts, "", " ")
- if err != nil {
- return err
- }
-
- cf := ContextsFile()
- if err := os.MkdirAll(filepath.Dir(cf), 0700); err != nil {
- return errs.FileError(err, cf)
- }
- if err := os.WriteFile(cf, b, 0600); err != nil {
- return errs.FileError(err, cf)
- }
-
- if cs.current == nil {
- if err := cs.SaveCurrent(ctx.Name); err != nil {
- return err
- }
- }
- return nil
-}
-
-// GetCurrent returns the current context.
-func (cs *CtxState) GetCurrent() *Context {
- return cs.current
-}
-
-// Get returns the context with the given name.
-func (cs *CtxState) Get(name string) (ctx *Context, ok bool) {
- ctx, ok = cs.contexts[name]
- return
-}
-
-// Remove removes a context from the context state.
-func (cs *CtxState) Remove(name string) error {
- if _, ok := cs.contexts[name]; !ok {
- return errors.Errorf("context '%s' not found", name)
- }
- if cs.current != nil && cs.current.Name == name {
- return errors.New("cannot remove current context; use 'step context select' to switch contexts")
- }
-
- delete(cs.contexts, name)
-
- b, err := json.MarshalIndent(cs.contexts, "", " ")
- if err != nil {
- return err
- }
-
- if err := os.WriteFile(ContextsFile(), b, 0600); err != nil {
- return fmt.Errorf("error writing file: %w", err)
- }
- return nil
-}
-
-// List returns a list of all contexts.
-func (cs *CtxState) List() []*Context {
- l := make([]*Context, 0, len(cs.contexts))
-
- for _, v := range cs.contexts {
- l = append(l, v)
- }
- return l
-}
-
-// ListAlphabetical returns a case-insensitive, alphabetically
-// sorted list of all contexts.
-func (cs *CtxState) ListAlphabetical() []*Context {
- l := cs.List()
-
- sort.Slice(l, func(i, j int) bool {
- return strings.ToLower(l[i].Name) < strings.ToLower(l[j].Name)
- })
-
- return l
-}
-
-// SaveCurrent stores the given context name as the selected default context for
-// future commands.
-func (cs *CtxState) SaveCurrent(name string) error {
- if _, ok := Contexts().Get(name); !ok {
- return errors.Errorf("context '%s' not found", name)
- }
-
- b, err := json.Marshal(storedCurrent{Context: name})
- if err != nil {
- return err
- }
- //nolint:gosec // this file does not contain sensitive info
- if err = os.WriteFile(CurrentContextFile(), b, 0644); err != nil {
- return errs.FileError(err, CurrentContextFile())
- }
- return nil
-}
-
-// Apply the current context configuration to the command line environment.
-func (cs *CtxState) Apply(ctx *cli.Context) error {
- cfg, err := cs.GetConfig()
- if err != nil {
- return err
- }
- for _, f := range ctx.Command.Flags {
- // Skip if EnvVar == IgnoreEnvVar
- if getFlagEnvVar(f) == IgnoreEnvVar {
- continue
- }
-
- for _, name := range strings.Split(f.GetName(), ",") {
- name = strings.TrimSpace(name)
- if ctx.IsSet(name) {
- break
- }
- // Set the flag for the first key that matches.
- if v, ok := cfg[name]; ok {
- ctx.Set(name, fmt.Sprintf("%v", v))
- break
- }
- }
- }
- return nil
-}
-
-// getEnvVar generates the environment variable for the given flag name.
-func getEnvVar(name string) string {
- parts := strings.Split(name, ",")
- name = strings.TrimSpace(parts[0])
- name = strings.ReplaceAll(name, "-", "_")
- return "STEP_" + strings.ToUpper(name)
-}
-
-// getFlagEnvVar returns the value of the EnvVar field of a flag.
-func getFlagEnvVar(f cli.Flag) string {
- v := reflect.ValueOf(f)
- if v.Kind() == reflect.Ptr {
- v = v.Elem()
- }
- if v.Kind() == reflect.Struct {
- envVar := v.FieldByName("EnvVar")
- if envVar.IsValid() {
- return envVar.String()
- }
- }
- return ""
-}
-
-// SetEnvVar sets the the EnvVar element to each flag recursively.
-func SetEnvVar(c *cli.Command) {
- if c == nil {
- return
- }
-
- // Enable getting the flags from a json file
- if c.Before == nil && c.Action != nil {
- c.Before = getConfigVars
- }
-
- // Enable getting the flags from environment variables
- for i := range c.Flags {
- envVar := getEnvVar(c.Flags[i].GetName())
- switch f := c.Flags[i].(type) {
- case cli.BoolFlag:
- if f.EnvVar == "" {
- f.EnvVar = envVar
- c.Flags[i] = f
- }
- case cli.BoolTFlag:
- if f.EnvVar == "" {
- f.EnvVar = envVar
- c.Flags[i] = f
- }
- case cli.DurationFlag:
- if f.EnvVar == "" {
- f.EnvVar = envVar
- c.Flags[i] = f
- }
- case cli.Float64Flag:
- if f.EnvVar == "" {
- f.EnvVar = envVar
- c.Flags[i] = f
- }
- case cli.GenericFlag:
- if f.EnvVar == "" {
- f.EnvVar = envVar
- c.Flags[i] = f
- }
- case cli.Int64Flag:
- if f.EnvVar == "" {
- f.EnvVar = envVar
- c.Flags[i] = f
- }
- case cli.IntFlag:
- if f.EnvVar == "" {
- f.EnvVar = envVar
- c.Flags[i] = f
- }
- case cli.IntSliceFlag:
- if f.EnvVar == "" {
- f.EnvVar = envVar
- c.Flags[i] = f
- }
- case cli.Int64SliceFlag:
- if f.EnvVar == "" {
- f.EnvVar = envVar
- c.Flags[i] = f
- }
- case cli.StringFlag:
- if f.EnvVar == "" {
- f.EnvVar = envVar
- c.Flags[i] = f
- }
- case cli.StringSliceFlag:
- if f.EnvVar == "" {
- f.EnvVar = envVar
- c.Flags[i] = f
- }
- case cli.Uint64Flag:
- if f.EnvVar == "" {
- f.EnvVar = envVar
- c.Flags[i] = f
- }
- case cli.UintFlag:
- if f.EnvVar == "" {
- f.EnvVar = envVar
- c.Flags[i] = f
- }
- }
- }
-
- for i := range c.Subcommands {
- SetEnvVar(&c.Subcommands[i])
- }
-}
-
-// GetConfigVars load the defaults.json file and sets the flags if they are not
-// already set or the EnvVar is set to IgnoreEnvVar.
-//
-// TODO(mariano): right now it only supports parameters at first level.
-func getConfigVars(ctx *cli.Context) (err error) {
- if ctx.Bool("no-context") {
- return nil
- }
-
- cs := Contexts()
-
- // Load the the current context into memory:
- // - If contexts enabled then make sure a current context is selected
- // and loaded.
- // - If vintage context then check if overwritten by --config flag.
- if cs.Enabled() {
- if ctx.IsSet("context") {
- err = cs.SetCurrent(ctx.String("context"))
- } else if cs.Enabled() && cs.GetCurrent() == nil {
- err = cs.PromptContext()
- }
- if err != nil {
- return err
- }
- } else if ctx.GlobalString("config") != "" {
- // Re-load the vintage context configuration if `--config` flag supplied.
- cs.LoadVintage(ctx.GlobalString("config"))
- }
-
- // TODO: a mock detail because of "add detail/assignee to this TODO/FIXME/BUG comment" lint issue
- fullCommandName := strings.ToLower(strings.TrimSpace(ctx.Command.FullName()))
- if strings.EqualFold(fullCommandName, "ca bootstrap-helper") {
- return nil
- }
-
- if err := cs.Apply(ctx); err != nil {
- return fmt.Errorf("error applying contexts: %w", err)
- }
-
- return nil
-}
diff --git a/vendor/github.com/smallstep/cli-utils/ui/options.go b/vendor/github.com/smallstep/cli-utils/ui/options.go
deleted file mode 100644
index 382c263..0000000
--- a/vendor/github.com/smallstep/cli-utils/ui/options.go
+++ /dev/null
@@ -1,172 +0,0 @@
-package ui
-
-import (
- "fmt"
- "regexp"
- "strings"
-
- "github.com/manifoldco/promptui"
-)
-
-type options struct {
- mask rune
- defaultValue string
- value string
- allowEdit bool
- printTemplate string
- promptTemplates *promptui.PromptTemplates
- selectTemplates *promptui.SelectTemplates
- validateFunc promptui.ValidateFunc
-}
-
-// apply applies the given options.
-func (o *options) apply(opts []Option) *options {
- for _, fn := range opts {
- fn(o)
- }
- return o
-}
-
-// valid returns true if the validate function passes on the value.
-func (o *options) valid() bool {
- if o.validateFunc == nil {
- return true
- }
- return o.validateFunc(o.value) == nil
-}
-
-// getValue validates the value and returns it.
-func (o *options) getValue() (string, error) {
- if o.validateFunc == nil {
- return o.value, nil
- }
- if err := o.validateFunc(o.value); err != nil {
- return "", err
- }
- return o.value, nil
-}
-
-// getValueBytes validates the value and returns it as a byte slice.
-func (o *options) getValueBytes() ([]byte, error) {
- if o.validateFunc == nil {
- return []byte(o.value), nil
- }
- if err := o.validateFunc(o.value); err != nil {
- return nil, err
- }
- return []byte(o.value), nil
-}
-
-// Option is the type of the functions that modify the prompt options.
-type Option func(*options)
-
-func extractOptions(args []interface{}) (opts []Option, rest []interface{}) {
- rest = args[:0]
- for _, arg := range args {
- if o, ok := arg.(Option); ok {
- opts = append(opts, o)
- } else {
- rest = append(rest, arg)
- }
- }
- return
-}
-
-// WithMask adds a mask to a prompt.
-func WithMask(r rune) Option {
- return func(o *options) {
- o.mask = r
- }
-}
-
-// WithDefaultValue adds a custom string as the default value.
-func WithDefaultValue(s string) Option {
- return func(o *options) {
- o.defaultValue = s
- }
-}
-
-// WithSliceValue sets a custom string as the result of a prompt. If value is set,
-// the prompt won't be displayed.
-func WithSliceValue(values []string) Option {
- return func(o *options) {
- o.value = strings.Join(values, ",")
- }
-}
-
-// WithValue sets a custom string as the result of a prompt. If value is set,
-// the prompt won't be displayed.
-func WithValue(value string) Option {
- return func(o *options) {
- o.value = value
- }
-}
-
-// WithAllowEdit if true, let's the user edit the default value set.
-func WithAllowEdit(b bool) Option {
- return func(o *options) {
- o.allowEdit = b
- }
-}
-
-// WithPrintTemplate sets the template to use on the print methods.
-func WithPrintTemplate(template string) Option {
- return func(o *options) {
- o.printTemplate = template
- }
-}
-
-// WithPromptTemplates adds a custom template to a prompt.
-func WithPromptTemplates(t *promptui.PromptTemplates) Option {
- return func(o *options) {
- o.promptTemplates = t
- }
-}
-
-// WithSelectTemplates adds a custom template to a select.
-func WithSelectTemplates(t *promptui.SelectTemplates) Option {
- return func(o *options) {
- o.selectTemplates = t
- }
-}
-
-// WithValidateFunc adds a custom validation function to a prompt.
-func WithValidateFunc(fn func(string) error) Option {
- return func(o *options) {
- o.validateFunc = fn
- }
-}
-
-// WithValidateNotEmpty adds a custom validation function to a prompt that
-// checks that the propted string is not empty.
-func WithValidateNotEmpty() Option {
- return WithValidateFunc(NotEmpty())
-}
-
-// WithValidateYesNo adds a custom validation function to a prompt for a Yes/No
-// prompt.
-func WithValidateYesNo() Option {
- return WithValidateFunc(YesNo())
-}
-
-// WithRichPrompt add the template option with rich templates.
-func WithRichPrompt() Option {
- return WithPromptTemplates(PromptTemplates())
-}
-
-// WithSimplePrompt add the template option with simple templates.
-func WithSimplePrompt() Option {
- return WithPromptTemplates(SimplePromptTemplates())
-}
-
-// WithValidateRegexp checks a prompt answer with a regular expression. If the
-// regular expression is not a valid one, the option will panic.
-func WithValidateRegexp(re string) Option {
- rx := regexp.MustCompile(re)
- return WithValidateFunc(func(s string) error {
- if rx.MatchString(s) {
- return nil
- }
- return fmt.Errorf("%s does not match the regular expresion %s", s, re)
- })
-}
diff --git a/vendor/github.com/smallstep/cli-utils/ui/templates.go b/vendor/github.com/smallstep/cli-utils/ui/templates.go
deleted file mode 100644
index cc37891..0000000
--- a/vendor/github.com/smallstep/cli-utils/ui/templates.go
+++ /dev/null
@@ -1,93 +0,0 @@
-package ui
-
-import (
- "fmt"
- "runtime"
-
- "github.com/chzyer/readline"
- "github.com/manifoldco/promptui"
-)
-
-var (
- // IconInitial is the icon used when starting in prompt mode and the icon next to the label when
- // starting in select mode.
- IconInitial = promptui.Styler(promptui.FGBlue)("?")
-
- // IconGood is the icon used when a good answer is entered in prompt mode.
- IconGood = promptui.Styler(promptui.FGGreen)("✔")
-
- // IconWarn is the icon used when a good, but potentially invalid answer is entered in prompt mode.
- IconWarn = promptui.Styler(promptui.FGYellow)("⚠")
-
- // IconBad is the icon used when a bad answer is entered in prompt mode.
- IconBad = promptui.Styler(promptui.FGRed)("✗")
-
- // IconSelect is the icon used to identify the currently selected item in select mode.
- IconSelect = promptui.Styler(promptui.FGBold)("▸")
-)
-
-func init() {
- // Set VT100 characters for windows too
- if runtime.GOOS == "windows" {
- promptui.KeyEnter = readline.CharEnter
- promptui.KeyBackspace = readline.CharBackspace
- promptui.KeyPrev = readline.CharPrev
- promptui.KeyPrevDisplay = "↑"
- promptui.KeyNext = readline.CharNext
- promptui.KeyNextDisplay = "↓"
- promptui.KeyBackward = readline.CharBackward
- promptui.KeyBackwardDisplay = "←"
- promptui.KeyForward = readline.CharForward
- promptui.KeyForwardDisplay = "→"
- }
-}
-
-// PrintSelectedTemplate returns the default template used in PrintSelected.
-func PrintSelectedTemplate() string {
- return fmt.Sprintf(`{{ %q | green }} {{ .Name | bold }}{{ ":" | bold }} {{ .Value }}`, IconGood) + "\n"
-}
-
-// PromptTemplates is the default style for a prompt.
-func PromptTemplates() *promptui.PromptTemplates {
- bold := promptui.Styler(promptui.FGBold)
- return &promptui.PromptTemplates{
- Prompt: fmt.Sprintf("%s {{ . | bold }}%s ", IconInitial, bold(":")),
- Success: fmt.Sprintf("%s {{ . | bold }}%s ", bold(IconGood), bold(":")),
- // Confirm: fmt.Sprintf(`{{ "%s" | bold }} {{ . | bold }}? {{ "[]" | faint }} `, IconInitial),
- Valid: fmt.Sprintf("%s {{ . | bold }}%s ", bold(IconGood), bold(":")),
- Invalid: fmt.Sprintf("%s {{ . | bold }}%s ", bold(IconBad), bold(":")),
- }
-}
-
-// SimplePromptTemplates is a prompt with a simple style, used by default on password prompts.
-func SimplePromptTemplates() *promptui.PromptTemplates {
- return &promptui.PromptTemplates{
- Prompt: "{{ . }}: ",
- Success: "{{ . }}: ",
- Valid: "{{ . }}: ",
- Invalid: "{{ . }}: ",
- }
-}
-
-// SelectTemplates returns the default promptui.SelectTemplate for string
-// slices. The given name is the prompt of the selected option.
-func SelectTemplates(name string) *promptui.SelectTemplates {
- return &promptui.SelectTemplates{
- Label: fmt.Sprintf("%s {{ . }}: ", IconInitial),
- Active: fmt.Sprintf("%s {{ . | underline }}", IconSelect),
- Inactive: " {{ . }}",
- Selected: fmt.Sprintf(`{{ %q | green }} {{ "%s:" | bold }} {{ .Name }}`, IconGood, name),
- }
-}
-
-// NamedSelectTemplates returns the default promptui.SelectTemplate for struct
-// slices with a name property. The given name is the prompt of the selected
-// option.
-func NamedSelectTemplates(name string) *promptui.SelectTemplates {
- return &promptui.SelectTemplates{
- Label: fmt.Sprintf("%s {{.Name}}: ", IconInitial),
- Active: fmt.Sprintf("%s {{ .Name | underline }}", IconSelect),
- Inactive: " {{.Name}}",
- Selected: fmt.Sprintf(`{{ %q | green }} {{ "%s:" | bold }} {{ .Name }}`, IconGood, name),
- }
-}
diff --git a/vendor/github.com/smallstep/cli-utils/ui/ui.go b/vendor/github.com/smallstep/cli-utils/ui/ui.go
deleted file mode 100644
index 40fbc0d..0000000
--- a/vendor/github.com/smallstep/cli-utils/ui/ui.go
+++ /dev/null
@@ -1,334 +0,0 @@
-package ui
-
-import (
- "fmt"
- "os"
- "strings"
- "text/template"
-
- "github.com/chzyer/readline"
- "github.com/manifoldco/promptui"
- "github.com/pkg/errors"
- "go.step.sm/crypto/randutil"
-)
-
-// stderr implements an io.WriteCloser that skips the terminal bell character
-// (ASCII code 7), and writes the rest to os.Stderr. It's used to replace
-// readline.Stdout, that is the package used by promptui to display the prompts.
-type stderr struct{}
-
-// Write implements an io.WriterCloser over os.Stderr, but it skips the terminal
-// bell character.
-func (s *stderr) Write(b []byte) (int, error) {
- if len(b) == 1 && b[0] == readline.CharBell {
- return 0, nil
- }
- return os.Stderr.Write(b)
-}
-
-// Close implements an io.WriterCloser over os.Stderr.
-func (s *stderr) Close() error {
- return os.Stderr.Close()
-}
-
-func init() {
- readline.Stdout = &stderr{}
-}
-
-// Init initializes the terminal to be used by this package. This is generally a
-// noop except for windows.
-func Init() {
- setConsoleMode()
-}
-
-// Reset sets the terminal as it was before the initialization. This is
-// generally a noop except for windows.
-func Reset() {
- resetConsoleMode()
-}
-
-// Print uses templates to print the arguments formated to os.Stderr.
-func Print(args ...interface{}) error {
- var o options
- opts, args := extractOptions(args)
- o.apply(opts)
-
- // Return with a default value. This is useful when we split the question
- // and the response in two lines.
- if o.value != "" && o.valid() {
- return nil
- }
-
- text := fmt.Sprint(args...)
- t, err := template.New("Print").Funcs(promptui.FuncMap).Parse(text)
- if err != nil {
- return errors.Wrap(err, "error parsing template")
- }
- if err := t.Execute(os.Stderr, nil); err != nil {
- return errors.Wrap(err, "error executing template")
- }
- return nil
-}
-
-// Printf uses templates to print the string formated to os.Stderr.
-func Printf(format string, args ...interface{}) error {
- var o options
- opts, args := extractOptions(args)
- o.apply(opts)
-
- // Return with a default value. This is useful when we split the question
- // and the response in two lines.
- if o.value != "" && o.valid() {
- return nil
- }
-
- text := fmt.Sprintf(format, args...)
- t, err := template.New("Printf").Funcs(promptui.FuncMap).Parse(text)
- if err != nil {
- return errors.Wrap(err, "error parsing template")
- }
- if err := t.Execute(os.Stderr, nil); err != nil {
- return errors.Wrap(err, "error executing template")
- }
- return nil
-}
-
-// Println uses templates to print the given arguments to os.Stderr
-func Println(args ...interface{}) error {
- var o options
- opts, args := extractOptions(args)
- o.apply(opts)
-
- // Return with a default value. This is useful when we split the question
- // and the response in two lines.
- if o.value != "" && o.valid() {
- return nil
- }
-
- text := fmt.Sprintln(args...)
- t, err := template.New("Println").Funcs(promptui.FuncMap).Parse(text)
- if err != nil {
- return errors.Wrap(err, "error parsing template")
- }
- if err := t.Execute(os.Stderr, nil); err != nil {
- return errors.Wrap(err, "error executing template")
- }
- return nil
-}
-
-// PrintSelected prints the given name and value as if they were selected from a
-// promptui.Select.
-func PrintSelected(name, value string, opts ...Option) error {
- o := &options{
- printTemplate: PrintSelectedTemplate(),
- }
- o.apply(opts)
-
- t, err := template.New(name).Funcs(promptui.FuncMap).Parse(o.printTemplate)
- if err != nil {
- return errors.Wrap(err, "error parsing template")
- }
-
- data := struct {
- Name string
- Value string
- }{name, value}
- if err := t.Execute(os.Stderr, data); err != nil {
- return errors.Wrap(err, "error executing template")
- }
-
- return nil
-}
-
-// Prompt creates and runs a promptui.Prompt with the given label.
-func Prompt(label string, opts ...Option) (string, error) {
- o := &options{
- promptTemplates: PromptTemplates(),
- }
- o.apply(opts)
-
- // Return value if set
- if o.value != "" {
- return o.getValue()
- }
-
- // Prompt using the terminal
- clean, err := preparePromptTerminal()
- if err != nil {
- return "", err
- }
- defer clean()
-
- prompt := &promptui.Prompt{
- Label: label,
- Default: o.defaultValue,
- AllowEdit: o.allowEdit,
- Validate: o.validateFunc,
- Templates: o.promptTemplates,
- }
- value, err := prompt.Run()
- if err != nil {
- return "", errors.Wrap(err, "error running prompt")
- }
- return value, nil
-}
-
-// PromptPassword creates and runs a promptui.Prompt with the given label. This
-// prompt will mask the key entries with \r.
-func PromptPassword(label string, opts ...Option) ([]byte, error) {
- // Using a not printable character as they work better than \r
- o := &options{
- mask: 1,
- promptTemplates: SimplePromptTemplates(),
- }
- o.apply(opts)
-
- // Return value if set
- if o.value != "" {
- return o.getValueBytes()
- }
-
- // Prompt using the terminal
- clean, err := preparePromptTerminal()
- if err != nil {
- return nil, err
- }
- defer clean()
-
- prompt := &promptui.Prompt{
- Label: label,
- Mask: o.mask,
- Default: o.defaultValue,
- AllowEdit: o.allowEdit,
- Validate: o.validateFunc,
- Templates: o.promptTemplates,
- }
- pass, err := prompt.Run()
- if err != nil {
- return nil, errors.Wrap(err, "error reading password")
- }
- return []byte(pass), nil
-}
-
-// PromptPasswordGenerate creates and runs a promptui.Prompt with the given label.
-// This prompt will mask the key entries with \r. If the result password length
-// is 0, it will generate a new prompt with a generated password that can be
-// edited.
-func PromptPasswordGenerate(label string, opts ...Option) ([]byte, error) {
- pass, err := PromptPassword(label, opts...)
- if err != nil || len(pass) > 0 {
- return pass, err
- }
- passString, err := randutil.Alphanumeric(32)
- if err != nil {
- return nil, err
- }
- passString, err = Prompt("Password", WithDefaultValue(passString), WithAllowEdit(true), WithValidateNotEmpty())
- if err != nil {
- return nil, err
- }
- return []byte(passString), nil
-}
-
-// PromptYesNo creates and runs a promptui.Prompt with the given label, and
-// returns true if the answer is y/yes and false if the answer is n/no.
-func PromptYesNo(label string, opts ...Option) (bool, error) {
- opts = append([]Option{WithValidateYesNo()}, opts...)
- s, err := Prompt(label, opts...)
- if err != nil {
- return false, err
- }
- switch strings.ToLower(strings.TrimSpace(s)) {
- case "y", "yes":
- return true, nil
- case "n", "no":
- return false, nil
- default:
- return false, fmt.Errorf("%s is not a valid answer", s)
- }
-}
-
-// Select creates and runs a promptui.Select with the given label and items.
-func Select(label string, items interface{}, opts ...Option) (int, string, error) {
- o := &options{
- selectTemplates: SelectTemplates(label),
- }
- o.apply(opts)
-
- clean, err := prepareSelectTerminal()
- if err != nil {
- return 0, "", err
- }
- defer clean()
-
- prompt := &promptui.Select{
- Label: label,
- Items: items,
- Templates: o.selectTemplates,
- }
- n, s, err := prompt.Run()
- if err != nil {
- return 0, "", errors.Wrap(err, "error running prompt")
- }
- return n, s, nil
-}
-
-func preparePromptTerminal() (func(), error) {
- nothing := func() {}
- if !readline.DefaultIsTerminal() {
- tty, err := os.Open("/dev/tty")
- if err != nil {
- return nothing, errors.Wrap(err, "error allocating terminal")
- }
- clean := func() {
- tty.Close()
- }
-
- fd := int(tty.Fd())
- state, err := readline.MakeRaw(fd)
- if err != nil {
- defer clean()
- return nothing, errors.Wrap(err, "error making raw terminal")
- }
- stdin := readline.Stdin
- readline.Stdin = tty
- clean = func() {
- readline.Stdin = stdin
- readline.Restore(fd, state)
- tty.Close()
- }
- return clean, nil
- }
-
- return nothing, nil
-}
-
-func prepareSelectTerminal() (func(), error) {
- nothing := func() {}
- if !readline.DefaultIsTerminal() {
- tty, err := os.Open("/dev/tty")
- if err != nil {
- return nothing, errors.Wrap(err, "error allocating terminal")
- }
- clean := func() {
- tty.Close()
- }
-
- fd := int(tty.Fd())
- state, err := readline.MakeRaw(fd)
- if err != nil {
- defer clean()
- return nothing, errors.Wrap(err, "error making raw terminal")
- }
- stdin := os.Stdin
- os.Stdin = tty
- clean = func() {
- os.Stdin = stdin
- readline.Restore(fd, state)
- tty.Close()
- }
- return clean, nil
- }
-
- return nothing, nil
-}
diff --git a/vendor/github.com/smallstep/cli-utils/ui/ui_other.go b/vendor/github.com/smallstep/cli-utils/ui/ui_other.go
deleted file mode 100644
index f449b57..0000000
--- a/vendor/github.com/smallstep/cli-utils/ui/ui_other.go
+++ /dev/null
@@ -1,8 +0,0 @@
-//go:build !windows
-// +build !windows
-
-package ui
-
-func setConsoleMode() {}
-
-func resetConsoleMode() {}
diff --git a/vendor/github.com/smallstep/cli-utils/ui/ui_windows.go b/vendor/github.com/smallstep/cli-utils/ui/ui_windows.go
deleted file mode 100644
index 573bfcb..0000000
--- a/vendor/github.com/smallstep/cli-utils/ui/ui_windows.go
+++ /dev/null
@@ -1,51 +0,0 @@
-//go:build windows
-// +build windows
-
-package ui
-
-import (
- "fmt"
- "os"
-
- "golang.org/x/sys/windows"
-)
-
-var inMode, outMode uint32
-
-func init() {
- var _ = windows.GetConsoleMode(windows.Stdin, &inMode)
- var _ = windows.GetConsoleMode(windows.Stdout, &outMode)
-}
-
-func setConsoleMode() {
- in := inMode | windows.ENABLE_VIRTUAL_TERMINAL_INPUT
- out := outMode | windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING
-
- if inMode != 0 && inMode != in {
- if err := windows.SetConsoleMode(windows.Stdin, in); err != nil {
- fmt.Fprintf(os.Stderr, "Failed to set console mode: %v\n", err)
- }
- }
-
- if outMode != 0 && outMode != out {
- if err := windows.SetConsoleMode(windows.Stdout, out); err != nil {
- fmt.Fprintf(os.Stderr, "Failed to set console mode: %v\n", err)
- }
- }
-}
-
-func resetConsoleMode() {
- in := inMode | windows.ENABLE_VIRTUAL_TERMINAL_INPUT
- out := outMode | windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING
-
- if inMode != 0 && inMode != in {
- if err := windows.SetConsoleMode(windows.Stdin, inMode); err != nil {
- fmt.Fprintf(os.Stderr, "Failed to reset console mode: %v\n", err)
- }
- }
- if outMode != 0 && outMode != out {
- if err := windows.SetConsoleMode(windows.Stdout, outMode); err != nil {
- fmt.Fprintf(os.Stderr, "Failed to reset console mode: %v\n", err)
- }
- }
-}
diff --git a/vendor/github.com/smallstep/cli-utils/ui/validators.go b/vendor/github.com/smallstep/cli-utils/ui/validators.go
deleted file mode 100644
index 7d8b603..0000000
--- a/vendor/github.com/smallstep/cli-utils/ui/validators.go
+++ /dev/null
@@ -1,75 +0,0 @@
-package ui
-
-import (
- "errors"
- "fmt"
- "net"
- "strings"
-
- "github.com/manifoldco/promptui"
-)
-
-var errEmptyValue = errors.New("value is empty")
-
-// NotEmpty is a validation function that checks that the prompted string is not
-// empty.
-func NotEmpty() promptui.ValidateFunc {
- return func(s string) error {
- if strings.TrimSpace(s) == "" {
- return errEmptyValue
- }
- return nil
- }
-}
-
-// Address is a validation function that checks that the prompted string is a
-// valid TCP address.
-func Address() promptui.ValidateFunc {
- return func(s string) error {
- if _, _, err := net.SplitHostPort(s); err != nil {
- return fmt.Errorf("%s is not an TCP address", s)
- }
- return nil
- }
-}
-
-// IPAddress is validation function that checks that the prompted string is a
-// valid IP address.
-func IPAddress() promptui.ValidateFunc {
- return func(s string) error {
- if net.ParseIP(s) == nil {
- return fmt.Errorf("%s is not an ip address", s)
- }
- return nil
- }
-}
-
-// DNS is a validation function that checks that the prompted string is a valid
-// DNS name or IP address.
-func DNS() promptui.ValidateFunc {
- return func(s string) error {
- if strings.TrimSpace(s) == "" {
- return errEmptyValue
- }
- if ip := net.ParseIP(s); ip != nil {
- return nil
- }
- if _, _, err := net.SplitHostPort(s + ":443"); err != nil {
- return fmt.Errorf("%s is not a valid DNS name or IP address", s)
- }
- return nil
- }
-}
-
-// YesNo is a validation function that checks for a Yes/No answer.
-func YesNo() promptui.ValidateFunc {
- return func(s string) error {
- s = strings.ToLower(strings.TrimSpace(s))
- switch s {
- case "y", "yes", "n", "no":
- return nil
- default:
- return fmt.Errorf("%s is not a valid answer", s)
- }
- }
-}
diff --git a/vendor/github.com/smallstep/cli-utils/usage/css.go b/vendor/github.com/smallstep/cli-utils/usage/css.go
deleted file mode 100644
index e552534..0000000
--- a/vendor/github.com/smallstep/cli-utils/usage/css.go
+++ /dev/null
@@ -1,764 +0,0 @@
-package usage
-
-// CSS code replicating Github style.
-// From https://github.com/sindresorhus/github-markdown-css
-// MIT license
-var css = `@font-face {
- font-family: octicons-link;
- src: url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAZwABAAAAAACFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEU0lHAAAGaAAAAAgAAAAIAAAAAUdTVUIAAAZcAAAACgAAAAoAAQAAT1MvMgAAAyQAAABJAAAAYFYEU3RjbWFwAAADcAAAAEUAAACAAJThvmN2dCAAAATkAAAABAAAAAQAAAAAZnBnbQAAA7gAAACyAAABCUM+8IhnYXNwAAAGTAAAABAAAAAQABoAI2dseWYAAAFsAAABPAAAAZwcEq9taGVhZAAAAsgAAAA0AAAANgh4a91oaGVhAAADCAAAABoAAAAkCA8DRGhtdHgAAAL8AAAADAAAAAwGAACfbG9jYQAAAsAAAAAIAAAACABiATBtYXhwAAACqAAAABgAAAAgAA8ASm5hbWUAAAToAAABQgAAAlXu73sOcG9zdAAABiwAAAAeAAAAME3QpOBwcmVwAAAEbAAAAHYAAAB/aFGpk3jaTY6xa8JAGMW/O62BDi0tJLYQincXEypYIiGJjSgHniQ6umTsUEyLm5BV6NDBP8Tpts6F0v+k/0an2i+itHDw3v2+9+DBKTzsJNnWJNTgHEy4BgG3EMI9DCEDOGEXzDADU5hBKMIgNPZqoD3SilVaXZCER3/I7AtxEJLtzzuZfI+VVkprxTlXShWKb3TBecG11rwoNlmmn1P2WYcJczl32etSpKnziC7lQyWe1smVPy/Lt7Kc+0vWY/gAgIIEqAN9we0pwKXreiMasxvabDQMM4riO+qxM2ogwDGOZTXxwxDiycQIcoYFBLj5K3EIaSctAq2kTYiw+ymhce7vwM9jSqO8JyVd5RH9gyTt2+J/yUmYlIR0s04n6+7Vm1ozezUeLEaUjhaDSuXHwVRgvLJn1tQ7xiuVv/ocTRF42mNgZGBgYGbwZOBiAAFGJBIMAAizAFoAAABiAGIAznjaY2BkYGAA4in8zwXi+W2+MjCzMIDApSwvXzC97Z4Ig8N/BxYGZgcgl52BCSQKAA3jCV8CAABfAAAAAAQAAEB42mNgZGBg4f3vACQZQABIMjKgAmYAKEgBXgAAeNpjYGY6wTiBgZWBg2kmUxoDA4MPhGZMYzBi1AHygVLYQUCaawqDA4PChxhmh/8ODDEsvAwHgMKMIDnGL0x7gJQCAwMAJd4MFwAAAHjaY2BgYGaA4DAGRgYQkAHyGMF8NgYrIM3JIAGVYYDT+AEjAwuDFpBmA9KMDEwMCh9i/v8H8sH0/4dQc1iAmAkALaUKLgAAAHjaTY9LDsIgEIbtgqHUPpDi3gPoBVyRTmTddOmqTXThEXqrob2gQ1FjwpDvfwCBdmdXC5AVKFu3e5MfNFJ29KTQT48Ob9/lqYwOGZxeUelN2U2R6+cArgtCJpauW7UQBqnFkUsjAY/kOU1cP+DAgvxwn1chZDwUbd6CFimGXwzwF6tPbFIcjEl+vvmM/byA48e6tWrKArm4ZJlCbdsrxksL1AwWn/yBSJKpYbq8AXaaTb8AAHja28jAwOC00ZrBeQNDQOWO//sdBBgYGRiYWYAEELEwMTE4uzo5Zzo5b2BxdnFOcALxNjA6b2ByTswC8jYwg0VlNuoCTWAMqNzMzsoK1rEhNqByEyerg5PMJlYuVueETKcd/89uBpnpvIEVomeHLoMsAAe1Id4AAAAAAAB42oWQT07CQBTGv0JBhagk7HQzKxca2sJCE1hDt4QF+9JOS0nbaaYDCQfwCJ7Au3AHj+LO13FMmm6cl7785vven0kBjHCBhfpYuNa5Ph1c0e2Xu3jEvWG7UdPDLZ4N92nOm+EBXuAbHmIMSRMs+4aUEd4Nd3CHD8NdvOLTsA2GL8M9PODbcL+hD7C1xoaHeLJSEao0FEW14ckxC+TU8TxvsY6X0eLPmRhry2WVioLpkrbp84LLQPGI7c6sOiUzpWIWS5GzlSgUzzLBSikOPFTOXqly7rqx0Z1Q5BAIoZBSFihQYQOOBEdkCOgXTOHA07HAGjGWiIjaPZNW13/+lm6S9FT7rLHFJ6fQbkATOG1j2OFMucKJJsxIVfQORl+9Jyda6Sl1dUYhSCm1dyClfoeDve4qMYdLEbfqHf3O/AdDumsjAAB42mNgYoAAZQYjBmyAGYQZmdhL8zLdDEydARfoAqIAAAABAAMABwAKABMAB///AA8AAQAAAAAAAAAAAAAAAAABAAAAAA==) format('woff');
-}
-
-.wrapper {
- margin: 0 auto;
- max-width: 700px;
- padding: 20px 10px;
-}
-
-.markdown-body {
- -ms-text-size-adjust: 100%;
- -webkit-text-size-adjust: 100%;
- line-height: 1.5;
- color: #24292e;
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
- font-size: 16px;
- line-height: 1.5;
- word-wrap: break-word;
-}
-
-.markdown-body .pl-c {
- color: #6a737d;
-}
-
-.markdown-body .pl-c1,
-.markdown-body .pl-s .pl-v {
- color: #005cc5;
-}
-
-.markdown-body .pl-e,
-.markdown-body .pl-en {
- color: #6f42c1;
-}
-
-.markdown-body .pl-smi,
-.markdown-body .pl-s .pl-s1 {
- color: #24292e;
-}
-
-.markdown-body .pl-ent {
- color: #22863a;
-}
-
-.markdown-body .pl-k {
- color: #d73a49;
-}
-
-.markdown-body .pl-s,
-.markdown-body .pl-pds,
-.markdown-body .pl-s .pl-pse .pl-s1,
-.markdown-body .pl-sr,
-.markdown-body .pl-sr .pl-cce,
-.markdown-body .pl-sr .pl-sre,
-.markdown-body .pl-sr .pl-sra {
- color: #032f62;
-}
-
-.markdown-body .pl-v,
-.markdown-body .pl-smw {
- color: #e36209;
-}
-
-.markdown-body .pl-bu {
- color: #b31d28;
-}
-
-.markdown-body .pl-ii {
- color: #fafbfc;
- background-color: #b31d28;
-}
-
-.markdown-body .pl-c2 {
- color: #fafbfc;
- background-color: #d73a49;
-}
-
-.markdown-body .pl-c2::before {
- content: "^M";
-}
-
-.markdown-body .pl-sr .pl-cce {
- font-weight: bold;
- color: #22863a;
-}
-
-.markdown-body .pl-ml {
- color: #735c0f;
-}
-
-.markdown-body .pl-mh,
-.markdown-body .pl-mh .pl-en,
-.markdown-body .pl-ms {
- font-weight: bold;
- color: #005cc5;
-}
-
-.markdown-body .pl-mi {
- font-style: italic;
- color: #24292e;
-}
-
-.markdown-body .pl-mb {
- font-weight: bold;
- color: #24292e;
-}
-
-.markdown-body .pl-md {
- color: #b31d28;
- background-color: #ffeef0;
-}
-
-.markdown-body .pl-mi1 {
- color: #22863a;
- background-color: #f0fff4;
-}
-
-.markdown-body .pl-mc {
- color: #e36209;
- background-color: #ffebda;
-}
-
-.markdown-body .pl-mi2 {
- color: #f6f8fa;
- background-color: #005cc5;
-}
-
-.markdown-body .pl-mdr {
- font-weight: bold;
- color: #6f42c1;
-}
-
-.markdown-body .pl-ba {
- color: #586069;
-}
-
-.markdown-body .pl-sg {
- color: #959da5;
-}
-
-.markdown-body .pl-corl {
- text-decoration: underline;
- color: #032f62;
-}
-
-.markdown-body .octicon {
- display: inline-block;
- vertical-align: text-top;
- fill: currentColor;
-}
-
-.markdown-body a {
- background-color: transparent;
-}
-
-.markdown-body a:active,
-.markdown-body a:hover {
- outline-width: 0;
-}
-
-.markdown-body strong {
- font-weight: inherit;
-}
-
-.markdown-body strong {
- font-weight: bolder;
-}
-
-.markdown-body h1 {
- font-size: 2em;
- margin: 0.67em 0;
-}
-
-.markdown-body img {
- border-style: none;
-}
-
-.markdown-body code,
-.markdown-body kbd,
-.markdown-body pre {
- font-family: monospace, monospace;
- font-size: 1em;
-}
-
-.markdown-body hr {
- box-sizing: content-box;
- height: 0;
- overflow: visible;
-}
-
-.markdown-body input {
- font: inherit;
- margin: 0;
-}
-
-.markdown-body input {
- overflow: visible;
-}
-
-.markdown-body [type="checkbox"] {
- box-sizing: border-box;
- padding: 0;
-}
-
-.markdown-body * {
- box-sizing: border-box;
-}
-
-.markdown-body input {
- font-family: inherit;
- font-size: inherit;
- line-height: inherit;
-}
-
-.markdown-body a {
- color: #0366d6;
- text-decoration: none;
-}
-
-.markdown-body a:hover {
- text-decoration: underline;
-}
-
-.markdown-body strong {
- font-weight: 600;
-}
-
-.markdown-body hr {
- height: 0;
- margin: 15px 0;
- overflow: hidden;
- background: transparent;
- border: 0;
- border-bottom: 1px solid #dfe2e5;
-}
-
-.markdown-body hr::before {
- display: table;
- content: "";
-}
-
-.markdown-body hr::after {
- display: table;
- clear: both;
- content: "";
-}
-
-.markdown-body table {
- border-spacing: 0;
- border-collapse: collapse;
-}
-
-.markdown-body td,
-.markdown-body th {
- padding: 0;
-}
-
-.markdown-body h1,
-.markdown-body h2,
-.markdown-body h3,
-.markdown-body h4,
-.markdown-body h5,
-.markdown-body h6 {
- margin-top: 0;
- margin-bottom: 0;
-}
-
-.markdown-body h1 {
- font-size: 32px;
- font-weight: 600;
-}
-
-.markdown-body h2 {
- font-size: 24px;
- font-weight: 600;
-}
-
-.markdown-body h3 {
- font-size: 20px;
- font-weight: 600;
-}
-
-.markdown-body h4 {
- font-size: 16px;
- font-weight: 600;
-}
-
-.markdown-body h5 {
- font-size: 14px;
- font-weight: 600;
-}
-
-.markdown-body h6 {
- font-size: 12px;
- font-weight: 600;
-}
-
-.markdown-body p {
- margin-top: 0;
- margin-bottom: 10px;
-}
-
-.markdown-body blockquote {
- margin: 0;
-}
-
-.markdown-body ul,
-.markdown-body ol {
- padding-left: 0;
- margin-top: 0;
- margin-bottom: 0;
-}
-
-.markdown-body ol ol,
-.markdown-body ul ol {
- list-style-type: lower-roman;
-}
-
-.markdown-body ul ul ol,
-.markdown-body ul ol ol,
-.markdown-body ol ul ol,
-.markdown-body ol ol ol {
- list-style-type: lower-alpha;
-}
-
-.markdown-body dd {
- margin-left: 0;
-}
-
-.markdown-body code {
- font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
- font-size: 12px;
-}
-
-.markdown-body pre {
- margin-top: 0;
- margin-bottom: 0;
- font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
- font-size: 12px;
-}
-
-.markdown-body .octicon {
- vertical-align: text-bottom;
-}
-
-.markdown-body .pl-0 {
- padding-left: 0 !important;
-}
-
-.markdown-body .pl-1 {
- padding-left: 4px !important;
-}
-
-.markdown-body .pl-2 {
- padding-left: 8px !important;
-}
-
-.markdown-body .pl-3 {
- padding-left: 16px !important;
-}
-
-.markdown-body .pl-4 {
- padding-left: 24px !important;
-}
-
-.markdown-body .pl-5 {
- padding-left: 32px !important;
-}
-
-.markdown-body .pl-6 {
- padding-left: 40px !important;
-}
-
-.markdown-body::before {
- display: table;
- content: "";
-}
-
-.markdown-body::after {
- display: table;
- clear: both;
- content: "";
-}
-
-.markdown-body>*:first-child {
- margin-top: 0 !important;
-}
-
-.markdown-body>*:last-child {
- margin-bottom: 0 !important;
-}
-
-.markdown-body a:not([href]) {
- color: inherit;
- text-decoration: none;
-}
-
-.markdown-body .anchor {
- float: left;
- padding-right: 4px;
- margin-left: -20px;
- line-height: 1;
-}
-
-.markdown-body .anchor:focus {
- outline: none;
-}
-
-.markdown-body p,
-.markdown-body blockquote,
-.markdown-body ul,
-.markdown-body ol,
-.markdown-body dl,
-.markdown-body table,
-.markdown-body pre {
- margin-top: 0;
- margin-bottom: 16px;
-}
-
-.markdown-body hr {
- height: 0.25em;
- padding: 0;
- margin: 24px 0;
- background-color: #e1e4e8;
- border: 0;
-}
-
-.markdown-body blockquote {
- padding: 0 1em;
- color: #6a737d;
- border-left: 0.25em solid #dfe2e5;
-}
-
-.markdown-body blockquote>:first-child {
- margin-top: 0;
-}
-
-.markdown-body blockquote>:last-child {
- margin-bottom: 0;
-}
-
-.markdown-body kbd {
- display: inline-block;
- padding: 3px 5px;
- font-size: 11px;
- line-height: 10px;
- color: #444d56;
- vertical-align: middle;
- background-color: #fafbfc;
- border: solid 1px #c6cbd1;
- border-bottom-color: #959da5;
- border-radius: 3px;
- box-shadow: inset 0 -1px 0 #959da5;
-}
-
-.markdown-body h1,
-.markdown-body h2,
-.markdown-body h3,
-.markdown-body h4,
-.markdown-body h5,
-.markdown-body h6 {
- margin-top: 24px;
- margin-bottom: 16px;
- font-weight: 600;
- line-height: 1.25;
-}
-
-.markdown-body h1 .octicon-link,
-.markdown-body h2 .octicon-link,
-.markdown-body h3 .octicon-link,
-.markdown-body h4 .octicon-link,
-.markdown-body h5 .octicon-link,
-.markdown-body h6 .octicon-link {
- color: #1b1f23;
- vertical-align: middle;
- visibility: hidden;
-}
-
-.markdown-body h1:hover .anchor,
-.markdown-body h2:hover .anchor,
-.markdown-body h3:hover .anchor,
-.markdown-body h4:hover .anchor,
-.markdown-body h5:hover .anchor,
-.markdown-body h6:hover .anchor {
- text-decoration: none;
-}
-
-.markdown-body h1:hover .anchor .octicon-link,
-.markdown-body h2:hover .anchor .octicon-link,
-.markdown-body h3:hover .anchor .octicon-link,
-.markdown-body h4:hover .anchor .octicon-link,
-.markdown-body h5:hover .anchor .octicon-link,
-.markdown-body h6:hover .anchor .octicon-link {
- visibility: visible;
-}
-
-.markdown-body h1 {
- padding-bottom: 0.3em;
- font-size: 2em;
- border-bottom: 1px solid #eaecef;
-}
-
-.markdown-body h2 {
- padding-bottom: 0.3em;
- font-size: 1.5em;
- border-bottom: 1px solid #eaecef;
-}
-
-.markdown-body h3 {
- font-size: 1.25em;
-}
-
-.markdown-body h4 {
- font-size: 1em;
-}
-
-.markdown-body h5 {
- font-size: 0.875em;
-}
-
-.markdown-body h6 {
- font-size: 0.85em;
- color: #6a737d;
-}
-
-.markdown-body ul,
-.markdown-body ol {
- padding-left: 2em;
-}
-
-.markdown-body ul ul,
-.markdown-body ul ol,
-.markdown-body ol ol,
-.markdown-body ol ul {
- margin-top: 0;
- margin-bottom: 0;
-}
-
-.markdown-body li {
- word-wrap: break-all;
-}
-
-.markdown-body li>p {
- margin-top: 16px;
-}
-
-.markdown-body li+li {
- margin-top: 0.25em;
-}
-
-.markdown-body dl {
- padding: 0;
-}
-
-.markdown-body dl dt {
- padding: 0;
- margin-top: 16px;
- font-size: 1em;
- font-style: italic;
- font-weight: 600;
-}
-
-.markdown-body dl dd {
- padding: 0 16px;
- margin-bottom: 16px;
-}
-
-.markdown-body table {
- display: block;
- width: 100%;
- overflow: auto;
-}
-
-.markdown-body table th {
- font-weight: 600;
-}
-
-.markdown-body table th,
-.markdown-body table td {
- padding: 6px 13px;
- border: 1px solid #dfe2e5;
-}
-
-.markdown-body table tr {
- background-color: #fff;
- border-top: 1px solid #c6cbd1;
-}
-
-.markdown-body table tr:nth-child(2n) {
- background-color: #f6f8fa;
-}
-
-.markdown-body img {
- max-width: 100%;
- box-sizing: content-box;
- background-color: #fff;
-}
-
-.markdown-body img[align=right] {
- padding-left: 20px;
-}
-
-.markdown-body img[align=left] {
- padding-right: 20px;
-}
-
-.markdown-body code {
- padding: 0.2em 0.4em;
- margin: 0;
- font-size: 85%;
- background-color: rgba(27,31,35,0.05);
- border-radius: 3px;
-}
-
-.markdown-body pre {
- word-wrap: normal;
-}
-
-.markdown-body pre>code {
- padding: 0;
- margin: 0;
- font-size: 100%;
- word-break: normal;
- white-space: pre;
- background: transparent;
- border: 0;
-}
-
-.markdown-body .highlight {
- margin-bottom: 16px;
-}
-
-.markdown-body .highlight pre {
- margin-bottom: 0;
- word-break: normal;
-}
-
-.markdown-body .highlight pre,
-.markdown-body pre {
- padding: 16px;
- overflow: auto;
- font-size: 85%;
- line-height: 1.45;
- background-color: #f6f8fa;
- border-radius: 3px;
-}
-
-.markdown-body pre code {
- display: inline;
- max-width: auto;
- padding: 0;
- margin: 0;
- overflow: visible;
- line-height: inherit;
- word-wrap: normal;
- background-color: transparent;
- border: 0;
-}
-
-.markdown-body .full-commit .btn-outline:not(:disabled):hover {
- color: #005cc5;
- border-color: #005cc5;
-}
-
-.markdown-body kbd {
- display: inline-block;
- padding: 3px 5px;
- font: 11px "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
- line-height: 10px;
- color: #444d56;
- vertical-align: middle;
- background-color: #fafbfc;
- border: solid 1px #d1d5da;
- border-bottom-color: #c6cbd1;
- border-radius: 3px;
- box-shadow: inset 0 -1px 0 #c6cbd1;
-}
-
-.markdown-body :checked+.radio-label {
- position: relative;
- z-index: 1;
- border-color: #0366d6;
-}
-
-.markdown-body .task-list-item {
- list-style-type: none;
-}
-
-.markdown-body .task-list-item+.task-list-item {
- margin-top: 3px;
-}
-
-.markdown-body .task-list-item input {
- margin: 0 0.2em 0.25em -1.6em;
- vertical-align: middle;
-}
-
-.markdown-body hr {
- border-bottom-color: #eee;
-}
-
-.command {
- font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier,
- monospace;
- font-size: 16px;
- padding-left: 40px;
-
-}
-
-.command h1 {
- border: none;
- margin-left: -40px;
-}
-
-.command h2 {
- border: none;
- margin-top: 2em;
- margin-left: -40px;
- font-size: 18px;
-}
-
-.command>ul {
- padding-left: 0;
-}
-
-.command ul {
- list-style-type: none;
-}
-
-.command table {
- margin: 2em 0 1em;
- display: block;
- width: 100%;
- overflow: auto;
- border-collapse: collapse;
-}
-
-.command table th {
- font-weight: 600;
-}
-
-.command table th,
-.command table td {
- padding: 6px 13px;
- border: 1px solid #dfe2e5;
-}
-
-.command table tr {
- background-color: #fff;
- border-top: 1px solid #c6cbd1;
-}
-
-.command table tr:nth-child(2n) {
- background-color: #f6f8fa;
-}
-
-
-`
diff --git a/vendor/github.com/smallstep/cli-utils/usage/help.go b/vendor/github.com/smallstep/cli-utils/usage/help.go
deleted file mode 100644
index eef3273..0000000
--- a/vendor/github.com/smallstep/cli-utils/usage/help.go
+++ /dev/null
@@ -1,191 +0,0 @@
-package usage
-
-import (
- "fmt"
- "strings"
-
- "github.com/urfave/cli"
-)
-
-// HelpCommandAction is the action function of the overwritten help command.
-var HelpCommandAction = cli.ActionFunc(helpAction)
-
-// HelpCommand overwrites default urfvafe/cli help command to support one or
-// multiple subcommands like:
-//
-// step help
-// step help crypto
-// step help crypto jwt
-// step help crypto jwt sign
-// ...
-func HelpCommand() cli.Command {
- return cli.Command{
- Name: "help",
- Aliases: []string{"h"},
- Usage: "display help for the specified command or command group",
- UsageText: "**step help** <command>",
- Description: `**step help** command displays help for a command or command group.
-
-## EXAMPLES
-
-Display help for **step ca certificate**:
-'''
-$ step help ca certificate
-'''
-
-Display help for **step ssh**:
-'''
-$ step help ssh
-'''`,
- Action: HelpCommandAction,
- Flags: []cli.Flag{
- cli.StringFlag{
- Name: "http",
- Usage: "HTTP service address (e.g., ':8080')",
- },
- cli.StringFlag{
- Name: "html",
- Usage: "The export <directory> for HTML docs.",
- },
- cli.StringFlag{
- Name: "markdown",
- Usage: "The export <directory> for Markdown docs.",
- },
- cli.BoolFlag{
- Name: "report",
- Usage: "Writes a JSON report to the HTML docs directory.",
- },
- },
- }
-}
-
-func helpAction(ctx *cli.Context) error {
- // use html version
- if ctx.IsSet("http") {
- return httpHelpAction(ctx)
- }
-
- if ctx.IsSet("html") {
- return htmlHelpAction(ctx)
- }
-
- if ctx.IsSet("markdown") {
- return markdownHelpAction(ctx)
- }
-
- args := ctx.Args()
- if args.Present() {
- last := len(args) - 1
- lastName := args[last]
- subcmd := ctx.App.Commands
- parent := createParentCommand(ctx)
-
- for _, name := range args[:last] {
- for _, cmd := range subcmd {
- if cmd.HasName(name) {
- parent = cmd
- subcmd = cmd.Subcommands
- break
- }
- }
- }
-
- for _, cmd := range subcmd {
- if !cmd.HasName(lastName) {
- continue
- }
- cmd.HelpName = fmt.Sprintf("%s %s", ctx.App.HelpName, strings.Join(args, " "))
- parent.HelpName = fmt.Sprintf("%s %s", ctx.App.HelpName, strings.Join(args[:last], " "))
-
- ctx.Command = cmd
- if len(cmd.Subcommands) == 0 {
- ctx.App = createCliApp(ctx, parent)
- return cli.ShowCommandHelp(ctx, lastName)
- }
-
- ctx.App = createCliApp(ctx, cmd)
- return cli.ShowCommandHelp(ctx, "")
- }
-
- return cli.NewExitError(fmt.Sprintf("No help topic for '%s %s'", ctx.App.Name, strings.Join(args, " ")), 3)
- }
-
- cli.ShowAppHelp(ctx)
- return nil
-}
-
-// createParentCommand returns a command representation of the app.
-func createParentCommand(ctx *cli.Context) cli.Command {
- return cli.Command{
- Name: ctx.App.Name,
- HelpName: ctx.App.HelpName,
- Usage: ctx.App.Usage,
- UsageText: ctx.App.UsageText,
- ArgsUsage: ctx.App.ArgsUsage,
- Description: ctx.App.Description,
- Subcommands: ctx.App.Commands,
- Flags: ctx.App.Flags,
- }
-}
-
-// createCliApp is re-implementation of urfave/cli method (in command.go):
-//
-// func (c Command) startApp(ctx *Context) error
-//
-// It lets us show the subcommands when help is executed like:
-//
-// step help foo
-// step help foo bar
-// ...
-func createCliApp(ctx *cli.Context, cmd cli.Command) *cli.App {
- app := cli.NewApp()
- app.Metadata = ctx.App.Metadata
-
- // set the name and usage
- app.Name = cmd.HelpName
- app.HelpName = cmd.HelpName
-
- app.Usage = cmd.Usage
- app.UsageText = cmd.UsageText
- app.Description = cmd.Description
- app.ArgsUsage = cmd.ArgsUsage
-
- // set CommandNotFound
- app.CommandNotFound = ctx.App.CommandNotFound
- app.CustomAppHelpTemplate = cmd.CustomHelpTemplate
-
- // set the flags and commands
- app.Commands = cmd.Subcommands
- app.Flags = cmd.Flags
-
- app.Version = ctx.App.Version
- app.Compiled = ctx.App.Compiled
- app.Author = ctx.App.Author
- app.Email = ctx.App.Email
- app.Writer = ctx.App.Writer
- app.ErrWriter = ctx.App.ErrWriter
-
- // Do not show help or version on subcommands
- app.HideHelp = true
- app.HideVersion = true
-
- // bash completion
- app.EnableBashCompletion = ctx.App.EnableBashCompletion
- if cmd.BashComplete != nil {
- app.BashComplete = cmd.BashComplete
- }
-
- // set the actions
- app.Before = cmd.Before
- app.After = cmd.After
-
- if cmd.Action != nil {
- app.Action = cmd.Action
- } else {
- app.Action = helpAction
- }
- app.OnUsageError = cmd.OnUsageError
-
- app.Setup()
- return app
-}
diff --git a/vendor/github.com/smallstep/cli-utils/usage/html.go b/vendor/github.com/smallstep/cli-utils/usage/html.go
deleted file mode 100644
index b2aaeb8..0000000
--- a/vendor/github.com/smallstep/cli-utils/usage/html.go
+++ /dev/null
@@ -1,351 +0,0 @@
-package usage
-
-import (
- "fmt"
- "net/http"
- "os"
- "path"
- "strings"
- "time"
-
- "github.com/urfave/cli"
-
- "github.com/smallstep/cli-utils/errs"
-)
-
-func httpHelpAction(ctx *cli.Context) error {
- addr := ctx.String("http")
- if addr == "" {
- return errs.RequiredFlag(ctx, "http")
- }
-
- fmt.Printf("Serving HTTP on %s ...\n", addr)
- server := http.Server{
- Addr: addr,
- Handler: &htmlHelpHandler{
- cliApp: ctx.App,
- },
- ReadHeaderTimeout: 15 * time.Second,
- }
- return server.ListenAndServe()
-}
-
-func markdownHelpAction(ctx *cli.Context) error {
- dir := path.Clean(ctx.String("markdown"))
- if err := os.MkdirAll(dir, 0755); err != nil {
- return errs.FileError(err, dir)
- }
-
- // app index
- index := path.Join(dir, "README.mdx")
- w, err := os.Create(index)
- if err != nil {
- return errs.FileError(err, index)
- }
- markdownHelpPrinter(w, mdAppHelpTemplate, "", ctx.App)
- if err := w.Close(); err != nil {
- return errs.FileError(err, index)
- }
-
- // Subcommands
- for _, cmd := range ctx.App.Commands {
- if err := markdownHelpCommand(ctx.App, cmd, cmd, path.Join(dir, cmd.Name)); err != nil {
- return err
- }
- }
- return nil
-}
-
-func markdownHelpCommand(app *cli.App, cmd, parent cli.Command, base string) error {
- if err := os.MkdirAll(base, 0755); err != nil {
- return errs.FileError(err, base)
- }
-
- fileName := "README.mdx"
-
- index := path.Join(base, fileName)
- w, err := os.Create(index)
- if err != nil {
- return errs.FileError(err, index)
- }
-
- parentName := parent.HelpName
- if cmd.HelpName == parent.HelpName {
- parentName = "step"
- }
-
- if len(cmd.Subcommands) == 0 {
- markdownHelpPrinter(w, mdCommandHelpTemplate, parentName, cmd)
- return errs.FileError(w.Close(), index)
- }
-
- ctx := cli.NewContext(app, nil, nil)
- ctx.App = createCliApp(ctx, cmd)
- markdownHelpPrinter(w, mdSubcommandHelpTemplate, parentName, ctx.App)
- if err := w.Close(); err != nil {
- return errs.FileError(err, index)
- }
-
- for _, sub := range cmd.Subcommands {
- sub.HelpName = fmt.Sprintf("%s %s", cmd.HelpName, sub.Name)
- if err := markdownHelpCommand(app, sub, cmd, path.Join(base, sub.Name)); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func htmlHelpAction(ctx *cli.Context) error {
- dir := path.Clean(ctx.String("html"))
-
- if err := os.MkdirAll(dir, 0755); err != nil {
- return errs.FileError(err, dir)
- }
-
- // app index
- index := path.Join(dir, "index.html")
- w, err := os.Create(index)
- if err != nil {
- return errs.FileError(err, index)
- }
-
- tophelp := htmlHelpPrinter(w, mdAppHelpTemplate, ctx.App)
- var report *Report
- if ctx.IsSet("report") {
- report = NewReport(ctx.App.Name, tophelp)
- }
-
- if err := w.Close(); err != nil {
- return errs.FileError(err, index)
- }
-
- // css style
- cssFile := path.Join(dir, "style.css")
- //nolint:gosec // not security sensitive
- if err := os.WriteFile(cssFile, []byte(css), 0666); err != nil {
- return errs.FileError(err, cssFile)
- }
-
- // Subcommands
- for _, cmd := range ctx.App.Commands {
- if err := htmlHelpCommand(ctx.App, cmd, path.Join(dir, cmd.Name), report); err != nil {
- return err
- }
- }
-
- // report
- if report != nil {
- repjson := path.Join(dir, "report.json")
- rjw, err := os.Create(repjson)
- if err != nil {
- return errs.FileError(err, repjson)
- }
-
- if err := report.Write(rjw); err != nil {
- return err
- }
-
- if err := rjw.Close(); err != nil {
- return errs.FileError(err, repjson)
- }
- }
-
- return nil
-}
-
-func htmlHelpCommand(app *cli.App, cmd cli.Command, base string, report *Report) error {
- if err := os.MkdirAll(base, 0755); err != nil {
- return errs.FileError(err, base)
- }
-
- index := path.Join(base, "index.html")
- w, err := os.Create(index)
- if err != nil {
- return errs.FileError(err, index)
- }
-
- if len(cmd.Subcommands) == 0 {
- cmdhelp := htmlHelpPrinter(w, mdCommandHelpTemplate, cmd)
-
- if report != nil {
- report.Process(cmd.HelpName, cmdhelp)
- }
-
- return errs.FileError(w.Close(), index)
- }
-
- ctx := cli.NewContext(app, nil, nil)
- ctx.App = createCliApp(ctx, cmd)
- subhelp := htmlHelpPrinter(w, mdSubcommandHelpTemplate, ctx.App)
-
- if report != nil {
- report.Process(cmd.HelpName, subhelp)
- }
-
- if err := w.Close(); err != nil {
- return errs.FileError(err, index)
- }
-
- for _, sub := range cmd.Subcommands {
- sub.HelpName = fmt.Sprintf("%s %s", cmd.HelpName, sub.Name)
- if err := htmlHelpCommand(app, sub, path.Join(base, sub.Name), report); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-type htmlHelpHandler struct {
- cliApp *cli.App
-}
-
-func (h *htmlHelpHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
- ctx := cli.NewContext(h.cliApp, nil, nil)
-
- // clean request URI
- requestURI := path.Clean(req.RequestURI)
- if requestURI == "/" {
- htmlHelpPrinter(w, mdAppHelpTemplate, ctx.App)
- return
- }
-
- if requestURI == "/style.css" {
- w.Header().Set("Content-Type", `text/css; charset="utf-8"`)
- w.Write([]byte(css))
- return
- }
-
- args := strings.Split(requestURI, "/")
- last := len(args) - 1
- lastName := args[last]
- subcmd := ctx.App.Commands
- for _, name := range args[:last] {
- for _, cmd := range subcmd {
- if cmd.HasName(name) {
- subcmd = cmd.Subcommands
- break
- }
- }
- }
-
- for _, cmd := range subcmd {
- if !cmd.HasName(lastName) {
- continue
- }
- cmd.HelpName = fmt.Sprintf("%s %s", ctx.App.HelpName, strings.Join(args, " "))
-
- ctx.Command = cmd
- if len(cmd.Subcommands) == 0 {
- htmlHelpPrinter(w, mdCommandHelpTemplate, cmd)
- return
- }
-
- ctx.App = createCliApp(ctx, cmd)
- htmlHelpPrinter(w, mdSubcommandHelpTemplate, ctx.App)
- return
- }
-
- http.NotFound(w, req)
-}
-
-// AppHelpTemplate contains the modified template for the main app
-var mdAppHelpTemplate = `## NAME
-**{{.HelpName}}** -- {{.Usage}}
-
-## USAGE
-
-'''raw
-{{if .UsageText}}{{.UsageText}}{{else}}**{{.HelpName}}**{{if .Commands}} <command>{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments]{{end}}{{end}}
-'''
-{{- if .Description}}
-
-## DESCRIPTION
-{{.Description}}{{end}}{{if .VisibleCommands}}
-
-## COMMANDS
-
-{{range .VisibleCategories}}{{if .Name}}{{.Name}}:{{end}}
-| Name | Usage |
-|---|---|{{range .VisibleCommands}}
-| **[{{join .Names ", "}}]({{.Name}}/)** | {{.Usage}} |{{end}}
-{{end}}{{if .VisibleFlags}}{{end}}
-
-## OPTIONS
-
-{{range $index, $option := .VisibleFlags}}{{if $index}}
-{{end}}{{$option}}
-{{end}}{{end}}{{if .Copyright}}{{if len .Authors}}
-
-## AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
-
-{{range $index, $author := .Authors}}{{if $index}}
-{{end}}{{$author}}{{end}}{{end}}{{if .Version}}{{if not .HideVersion}}
-
-## VERSION
-
-{{.Version}}{{end}}{{end}}
-
-## COPYRIGHT
-
-{{.Copyright}}
-{{end}}
-`
-
-// SubcommandHelpTemplate contains the modified template for a sub command
-// Note that the weird "|||\n|---|---|" syntax sets up a markdown table with empty headers.
-var mdSubcommandHelpTemplate = `## NAME
-**{{.HelpName}}** -- {{.Usage}}
-
-## USAGE
-
-'''raw
-{{if .UsageText}}{{.UsageText}}{{else}}**{{.HelpName}}** <command>{{if .VisibleFlags}} [options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments]{{end}}{{end}}
-'''
-{{- if .Description}}
-
-## DESCRIPTION
-
-{{.Description}}{{end}}
-
-## COMMANDS
-
-{{range .VisibleCategories}}{{if .Name}}{{.Name}}:{{end}}
-| Name | Usage |
-|---|---|{{range .VisibleCommands}}
-| **[{{join .Names ", "}}]({{.Name}}/)** | {{.Usage}} |{{end}}
-{{end}}{{if .VisibleFlags}}
-
-## OPTIONS
-
-{{range .VisibleFlags}}
-{{.}}
-{{end}}{{end}}
-`
-
-// CommandHelpTemplate contains the modified template for a command
-var mdCommandHelpTemplate = `## NAME
-**{{.HelpName}}** -- {{.Usage}}
-
-## USAGE
-
-'''raw
-{{if .UsageText}}{{.UsageText}}{{else}}**{{.HelpName}}**{{if .VisibleFlags}} [options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments]{{end}}{{end}}
-'''
-{{- if .Category}}
-
-## CATEGORY
-
-{{.Category}}{{end}}{{if .Description}}
-
-## DESCRIPTION
-
-{{.Description}}{{end}}{{if .VisibleFlags}}
-
-## OPTIONS
-
-{{range .VisibleFlags}}
-{{.}}
-{{end}}{{end}}
-`
diff --git a/vendor/github.com/smallstep/cli-utils/usage/printer.go b/vendor/github.com/smallstep/cli-utils/usage/printer.go
deleted file mode 100644
index 0a09680..0000000
--- a/vendor/github.com/smallstep/cli-utils/usage/printer.go
+++ /dev/null
@@ -1,235 +0,0 @@
-package usage
-
-import (
- "bytes"
- "fmt"
- "io"
- "regexp"
- "strings"
- "text/template"
- "unicode"
-
- "github.com/urfave/cli"
-
- md "github.com/smallstep/cli-utils/pkg/blackfriday"
-)
-
-var sectionRe = regexp.MustCompile(`(?m:^##)`)
-var sectionNameRe = regexp.MustCompile(`(?m:^## [^\n]+)`)
-var indentRe = regexp.MustCompile(`(?m:^:[^\n]+)`)
-var definitionListRe = regexp.MustCompile(`(?m:^[\t ]+\*\*[^\*]+\*\*[^\n]*\s+:[^\n]+)`)
-
-//var sectionRe = regexp.MustCompile(`^## [^\n]*$`)
-
-type frontmatterData struct {
- Data interface{}
- Parent string
- Children []string
-}
-
-// HelpPrinter overwrites cli.HelpPrinter and prints the formatted help to the terminal.
-func HelpPrinter(w io.Writer, templ string, data interface{}) {
- b := helpPreprocessor(w, templ, data, false)
- w.Write(Render(b))
-}
-
-func htmlHelpPrinter(w io.Writer, templ string, data interface{}) []byte {
- b := helpPreprocessor(w, templ, data, true)
- w.Write([]byte(`<html><head><title>step command line documentation</title>`))
- w.Write([]byte(`<link href="/style.css" rel="stylesheet" type="text/css">`))
- w.Write([]byte(`</head><body><div class="wrapper markdown-body command">`))
- html := md.Run(b)
- w.Write(html)
- w.Write([]byte(`</div></body></html>`))
-
- return html
-}
-
-func markdownHelpPrinter(w io.Writer, templ, parent string, data interface{}) {
- b := helpPreprocessor(w, templ, data, true)
-
- frontmatter := frontmatterData{
- Data: data,
- Parent: parent,
- }
-
- if app, ok := data.(*cli.App); ok {
- for _, cmd := range app.Commands {
- frontmatter.Children = append(frontmatter.Children, cmd.Name)
- }
- }
-
- var frontMatterTemplate = `---
-layout: auto-doc
-category: reference
-title: {{.Data.HelpName}}
-menu:
- docs:
-{{- if .Parent}}
- parent: {{.Parent}}
-{{- end }}
-{{- if .Children }}
- children:
-{{- range .Children }}
- - {{.}}
-{{- end }}
-{{- end }}
----
-
-`
- t, err := template.New("frontmatter").Parse(frontMatterTemplate)
- if err != nil {
- panic(err)
- }
- err = t.Execute(w, frontmatter)
- if err != nil {
- panic(err)
- }
- w.Write(b)
-}
-
-func helpPreprocessor(_ io.Writer, templ string, data interface{}, applyRx bool) []byte {
- buf := new(bytes.Buffer)
- cli.HelpPrinterCustom(buf, templ, data, nil)
- //w.Write(buf.Bytes())
- // s := string(markdownify(buf.Bytes()))
- s := markdownify(buf)
- // Move the OPTIONS section to the right place. urfave puts them at the end
- // of the file, we want them to be after POSITIONAL ARGUMENTS, DESCRIPTION,
- // USAGE, or NAME (in that order, depending on which sections exist).
- optLoc := strings.Index(s, "## OPTIONS")
- if optLoc != -1 {
- optEnd := findSectionEnd("OPTIONS", s)
- if optEnd != -1 {
- options := s[optLoc:optEnd]
- s = s[:optLoc] + s[optEnd:]
- if newLoc := findSectionEnd("POSITIONAL ARGUMENTS", s); newLoc != -1 {
- s = s[:newLoc] + options + s[newLoc:]
- } else if newLoc := findSectionEnd("DESCRIPTION", s); newLoc != -1 {
- s = s[:newLoc] + options + s[newLoc:]
- } else if newLoc := findSectionEnd("USAGE", s); newLoc != -1 {
- s = s[:newLoc] + options + s[newLoc:]
- } else if newLoc := findSectionEnd("NAME", s); newLoc != -1 {
- s = s[:newLoc] + options + s[newLoc:]
- } else {
- // Keep it at the end I guess :/.
- s += options
- }
- }
- }
-
- if applyRx {
- // Keep capitalized only the first letter in arguments names.
- s = sectionNameRe.ReplaceAllStringFunc(s, func(s string) string {
- return s[0:4] + strings.ToLower(s[4:])
- })
- // Remove `:` at the start of a line.
- s = indentRe.ReplaceAllStringFunc(s, func(s string) string {
- return strings.TrimSpace(s[1:])
- })
- // Convert lines like:
- // **Foo**
- // : Bar zar ...
- // To:
- // - **Foo**: Bar zar ...
- s = definitionListRe.ReplaceAllStringFunc(s, func(s string) string {
- i := strings.Index(s, "\n")
- j := strings.Index(s, ":")
- return "- " + strings.TrimSpace(s[:i]) + ": " + strings.TrimSpace(s[j+1:])
- })
- }
-
- return []byte(s)
-}
-
-func findSectionEnd(h, s string) int {
- start := strings.Index(s, fmt.Sprintf("## %s", h))
- if start == -1 {
- return start
- }
- nextSection := sectionRe.FindStringIndex(s[start+2:])
- if nextSection == nil {
- return len(s)
- }
- return start + 2 + nextSection[0]
-}
-
-// Convert some stuff that we can't easily write in help files because
-//
-// backticks and raw strings don't mix:
-//
-// - "<foo>" to "`foo`"
-// - "”'" to "```"
-func markdownify(r *bytes.Buffer) string {
- const escapeByte = byte('\\')
- var last byte
- var inCode bool
-
- w := new(bytes.Buffer)
- for {
- b, err := r.ReadByte()
- if err != nil {
- return w.String()
- }
- loop:
- switch b {
- case '<':
- if last != escapeByte && !inCode {
- w.WriteByte('`')
- } else {
- w.WriteByte(b)
- }
- case '>':
- if last != escapeByte && !inCode {
- w.WriteByte('`')
- } else {
- w.WriteByte(b)
- }
- case '\'':
- b1, _ := r.ReadByte()
- b2, _ := r.ReadByte()
- if b1 == b && b2 == b {
- w.WriteString("```")
- if !inCode {
- if n, _, err := r.ReadRune(); err == nil {
- if unicode.IsSpace(n) {
- w.WriteString("shell")
- }
- r.UnreadRune()
- }
- }
- inCode = !inCode
- } else {
- // We can only unread the last one (b2)
- w.WriteByte(b)
- r.UnreadByte()
- b = b1
- last = b
- goto loop
- }
- case '*':
- if inCode {
- if b1, _ := r.ReadByte(); b1 != '*' {
- w.WriteByte(b)
- w.UnreadByte()
- }
- } else {
- w.WriteByte(b)
- }
- case escapeByte:
- if last == escapeByte {
- w.WriteByte(escapeByte)
- b = 0
- } else if n, _, err := r.ReadRune(); err == nil {
- if unicode.IsSpace(n) {
- w.WriteByte(escapeByte)
- }
- r.UnreadRune()
- }
- case 0: // probably because io.EOF
- default:
- w.WriteByte(b)
- }
- last = b
- }
-}
diff --git a/vendor/github.com/smallstep/cli-utils/usage/renderer.go b/vendor/github.com/smallstep/cli-utils/usage/renderer.go
deleted file mode 100644
index 7fb1506..0000000
--- a/vendor/github.com/smallstep/cli-utils/usage/renderer.go
+++ /dev/null
@@ -1,373 +0,0 @@
-package usage
-
-import (
- "bufio"
- "bytes"
- "fmt"
- "io"
- "regexp"
- "strings"
- "text/tabwriter"
- "unicode"
-
- "github.com/mgutz/ansi"
-
- md "github.com/smallstep/cli-utils/pkg/blackfriday"
-)
-
-// Render renders the given data with a custom markdown renderer.
-func Render(b []byte) []byte {
- return md.Run(b, md.WithRenderer(&Renderer{6, 0, nil, nil, false}))
-}
-
-var colorEscapeRe = regexp.MustCompile(`\033\[\d*(;\d*)?m?\]?`)
-var maxLineLength = 80
-
-func stripColors(b []byte) []byte {
- return colorEscapeRe.ReplaceAll(b, []byte(""))
-}
-
-type item struct {
- flags md.ListType
- term []byte
- definitions [][]byte
-}
-
-type list struct {
- items []item
- flags md.ListType
- parent *list
-}
-
-/* TODO: commented because unused
-func (l *list) isUnordered() bool {
- return !l.isOrdered() && !l.isDefinition()
-}
-
-func (l *list) isOrdered() bool {
- return l.flags&md.ListTypeOrdered != 0
-}
-
-func (l *list) containsBlock() bool {
- // TODO: Not sure if we have to check every item or if it gets
- // automatically set on the list?
- return l.flags&md.ListItemContainsBlock != 0
-}
-*/
-
-func (l *list) isDefinition() bool {
- return l.flags&md.ListTypeDefinition != 0
-}
-
-type bufqueue struct {
- w io.Writer
- buf *bytes.Buffer
- next *bufqueue
- mode RenderMode
-}
-
-// RenderMode enumerates different line breaks modes.
-type RenderMode int
-
-const (
- // RenderModeKeepBreaks will keep the line breaks in the docs.
- RenderModeKeepBreaks RenderMode = iota
- // RenderModeBreakLines will automatically wrap the lines.
- RenderModeBreakLines
-)
-
-// Renderer implements a custom markdown renderer for blackfriday.
-type Renderer struct {
- depth int
- listdepth int
- list *list
- out *bufqueue
- inpara bool
-}
-
-func (r *Renderer) write(b []byte) {
- r.out.w.Write(b)
-}
-
-func (r *Renderer) printf(s string, a ...interface{}) {
- fmt.Fprintf(r.out.w, s, a...)
-}
-
-func (r *Renderer) capture(mode RenderMode) {
- buf := new(bytes.Buffer)
- r.out = &bufqueue{buf, buf, r.out, mode}
-}
-
-func (r *Renderer) finishCapture() *bytes.Buffer {
- buf := r.out.buf
- r.out = r.out.next
- return buf
-}
-
-func (r *Renderer) inParagraph() bool {
- return r.inpara
-}
-
-/* TODO: commented because unused
-func (r *Renderer) inList() bool {
- return r.list != nil
-}
-*/
-
-func (r *Renderer) renderParagraphKeepBreaks(buf *bytes.Buffer) {
- scanner := bufio.NewScanner(buf)
- for scanner.Scan() {
- r.printf(strings.Repeat(" ", r.depth)+"%s\n", scanner.Text())
- }
-}
-
-func (r *Renderer) renderParagraphBreakLines(buf *bytes.Buffer, maxlen int) {
- maxlen -= r.depth
- scanner := bufio.NewScanner(buf)
- scanner.Split(bufio.ScanWords)
- line := []string{}
- length := 0
- for scanner.Scan() {
- word := scanner.Text()
- wordLength := len(stripColors([]byte(word)))
- // Print the line if we've got a collection of words over 80 characters, or if
- // we have a single word that is over 80 characters on an otherwise empty line.
- switch {
- case length+wordLength > maxlen:
- r.printf(strings.Repeat(" ", r.depth)+"%s\n", strings.Join(line, " "))
- line = []string{word}
- length = wordLength
- case length == 0 && wordLength > maxlen:
- r.printf(strings.Repeat(" ", r.depth)+"%s\n", word)
- default:
- line = append(line, word)
- length += wordLength + 1 // Plus one for space
- }
- }
- if len(line) > 0 {
- r.printf(strings.Repeat(" ", r.depth)+"%s\n", strings.Join(line, " "))
- }
-}
-
-func (r *Renderer) renderParagraph(buf *bytes.Buffer) {
- switch r.out.mode {
- case RenderModeKeepBreaks:
- r.renderParagraphKeepBreaks(buf)
- case RenderModeBreakLines:
- r.renderParagraphBreakLines(buf, maxLineLength)
- }
-}
-
-// RenderNode implements blackfriday.Renderer interface.
-func (r *Renderer) RenderNode(w io.Writer, node *md.Node, entering bool) md.WalkStatus {
- if r.out == nil {
- r.out = &bufqueue{w, nil, nil, RenderModeBreakLines}
- }
-
- switch node.Type {
- case md.Paragraph:
- // Alternative idea here: call r.RenderNode() with our new buffer as
- // `w`. In the `else` condition here render to the outter buffer and
- // always return md.Terminate. So when we enter a paragraph we start
- // parsing with a new output buffer and capture the output.
- if entering {
- if r.inParagraph() {
- panic("already in paragraph")
- }
- r.inpara = true
- //r.printf(out, "[paragraph:")
- r.capture(r.out.mode)
- } else {
- r.renderParagraph(r.finishCapture())
- // Write a newline unless the parent node is a definition list term.
- if node.Parent.Type != md.Item || node.Parent.ListFlags&md.ListTypeTerm == 0 {
- r.printf("\n")
- }
- r.inpara = false
- //r.printf(w, ":paragraph]")
- }
- case md.Text:
- // TODO: is this necessary? I think all text is in a paragraph.
- if r.inParagraph() {
- r.write(node.Literal)
- } else {
- s := strings.ReplaceAll(string(node.Literal), "\n", "\n"+strings.Repeat(" ", r.depth))
- r.printf(s) //nolint:govet // allow non-constant
- }
- case md.Heading:
- if entering {
- r.printf(ansi.ColorCode("default+bh")) //nolint:govet // allow non-constant
- } else {
- r.printf(ansi.Reset)
- r.printf("\n")
- }
- case md.Link:
- if entering {
- r.printf(ansi.ColorCode("default+b")) //nolint:govet // allow non-constant
- //r.printf("\033[2m") // Dim
- } else {
- r.printf(ansi.Reset)
- }
- case md.Strong:
- if entering {
- r.printf(ansi.ColorCode("default+bh")) //nolint:govet // allow non-constant
- } else {
- r.printf(ansi.Reset)
- }
- case md.Emph:
- if entering {
- r.printf(ansi.ColorCode("default+u")) //nolint:govet // allow non-constant
- } else {
- r.printf(ansi.Reset)
- }
- case md.Code:
- r.printf(ansi.ColorCode("default+u")) //nolint:govet // allow non-constant
- r.write(node.Literal)
- r.printf(ansi.Reset)
- case md.List:
- if entering {
- r.listdepth++
- r.list = &list{[]item{}, node.ListFlags, r.list}
- //r.printf("[list (type %s:", node.ListData.ListFlags)
- } else {
- if r.listdepth > 1 && r.list.isDefinition() {
- w := new(tabwriter.Writer)
- w.Init(r.out.w, 0, 8, 4, ' ', tabwriter.StripEscape)
- for _, item := range r.list.items {
- fmt.Fprint(w, strings.TrimRight(string(item.term), " \n"))
- fmt.Fprint(w, "\n")
- for _, def := range item.definitions {
- fmt.Fprint(w, strings.TrimRight(string(def), " \n"))
- }
- fmt.Fprintf(w, "\n\n")
- }
- w.Flush()
- } else {
- ordered := (node.ListFlags&md.ListTypeOrdered != 0)
- unordered := (node.ListFlags&md.ListTypeOrdered == 0 && node.ListFlags&md.ListTypeDefinition == 0)
- for i, item := range r.list.items {
- if ordered || unordered {
- p := bytes.IndexFunc(item.term, func(r rune) bool { return !unicode.IsSpace(r) })
- switch {
- case ordered: // add numbers on ordered lists
- item.term = append(item.term[:p], append([]byte(fmt.Sprintf("%d. ", i+1)), item.term[p:]...)...)
- case unordered: // add bullet points on unordered lists
- item.term = append(item.term[:p], append([]byte("• "), item.term[p:]...)...)
- }
- }
-
- r.write(item.term)
- for _, def := range item.definitions {
- r.write(def)
- }
- }
- }
- r.listdepth--
- r.list = r.list.parent
- //r.printf(":list]")
- }
- case md.Item:
- incdepth := 4
- //ltype := "normal"
- if node.ListFlags&md.ListTypeTerm != 0 {
- // Nested definition list terms get indented two spaces. Non-nested
- // definition list terms are not indented.
- if r.listdepth > 1 {
- incdepth = 2
- } else {
- incdepth = 0
- }
- //ltype = "dt"
- } else if node.ListFlags&md.ListTypeDefinition != 0 {
- incdepth = 4
- //ltype = "dd"
- }
-
- if entering {
- //fmt.Fprintf(out, "[list item %s:", ltype)
- r.depth += incdepth
- if r.listdepth > 1 && r.list.isDefinition() {
- r.capture(RenderModeKeepBreaks)
- } else {
- r.capture(RenderModeBreakLines)
- }
- if !r.list.isDefinition() || node.ListFlags&md.ListTypeTerm != 0 {
- r.list.items = append(r.list.items, item{node.ListFlags, nil, nil})
- }
- } else {
- //fmt.Fprintf(out, ":list item]")
- r.depth -= incdepth
- buf := r.finishCapture()
- if r.list.isDefinition() && node.ListFlags&md.ListTypeTerm == 0 {
- i := len(r.list.items) - 1
- r.list.items[i].definitions = append(r.list.items[i].definitions, buf.Bytes())
- } else {
- r.list.items[len(r.list.items)-1].term = buf.Bytes()
- }
- }
- case md.Table:
- if entering {
- r.capture(RenderModeKeepBreaks)
- w := new(tabwriter.Writer)
- w.Init(r.out.w, 1, 8, 2, ' ', tabwriter.StripEscape)
- r.out.w = w
- } else {
- r.out.w.(*tabwriter.Writer).Flush()
- buf := r.finishCapture()
- r.renderParagraphKeepBreaks(buf)
- r.printf("\n")
- }
- case md.TableBody:
- // Do nothing.
- case md.TableHead:
- if entering {
- r.capture(r.out.mode)
- } else {
- // Markdown doens't have a way to create a table without headers.
- // We've opted to fix that here by not rendering headers at all if
- // they're empty.
- result := r.finishCapture().Bytes()
- if strings.TrimSpace(string(stripColors(result))) != "" {
- parts := strings.Split(strings.TrimRight(string(result), "\t\n"), "\t")
- for i := 0; i < len(parts); i++ {
- parts[i] = "\xff" + ansi.ColorCode("default+bh") + "\xff" + parts[i] + "\xff" + ansi.Reset + "\xff"
- }
- r.printf(strings.Join(parts, "\t") + "\t\n") //nolint:govet // allow non-constant
- }
- }
- case md.TableRow:
- if entering {
- r.capture(r.out.mode)
- } else {
- // Escape any colors in the row before writing to the
- // tabwriter, otherwise they screw up the width calculations. The
- // escape character for tabwriter is \xff.
- result := r.finishCapture().Bytes()
- result = colorEscapeRe.ReplaceAll(result, []byte("\xff$0\xff"))
- r.write(result)
- r.printf("\n")
- }
- case md.TableCell:
- if !entering {
- r.printf("\t")
- }
- case md.CodeBlock:
- r.depth += 4
- r.renderParagraphKeepBreaks(bytes.NewBuffer(node.Literal))
- r.printf("\n")
- r.depth -= 4
- case md.Document:
- default:
- r.printf("unknown block %s:", node.Type)
- r.write(node.Literal)
- }
- //w.Write([]byte(fmt.Sprintf("node<%s; %t>", node.Type, entering)))
- //w.Write(node.Literal)
- return md.GoToNext
-}
-
-// RenderHeader implements blackfriday.Renderer interface.
-func (r *Renderer) RenderHeader(io.Writer, *md.Node) {}
-
-// RenderFooter implements blackfriday.Renderer interface.
-func (r *Renderer) RenderFooter(io.Writer, *md.Node) {}
diff --git a/vendor/github.com/smallstep/cli-utils/usage/report.go b/vendor/github.com/smallstep/cli-utils/usage/report.go
deleted file mode 100644
index 14ed250..0000000
--- a/vendor/github.com/smallstep/cli-utils/usage/report.go
+++ /dev/null
@@ -1,148 +0,0 @@
-package usage
-
-import (
- "bytes"
- "encoding/json"
- "errors"
- "fmt"
- "io"
- "regexp"
- "strings"
-
- "golang.org/x/net/html"
-)
-
-// Section keeps track of individual sections
-type Section struct {
- Command string `json:"command"`
- Name string `json:"name"`
- Text string `json:"text"`
- Words int `json:"words"`
- Lines int `json:"lines"`
- Sections []*Section `json:"sections"`
-}
-
-// Report holds together a report of sections
-type Report struct {
- Report []*Section `json:"report"`
-}
-
-// NewReport returns report based on raw
-func NewReport(command string, top []byte) *Report {
- report := Report{}
- report.Process(command, top)
-
- return &report
-}
-
-// Write serializes the report to json
-func (report *Report) Write(w io.Writer) error {
- j, err := json.MarshalIndent(report, "", " ")
-
- if err != nil {
- return err
- }
-
- w.Write(j)
-
- return nil
-}
-
-// Process adds a html based help page to the report
-func (report *Report) Process(command string, raw []byte) error {
- r := bytes.NewBuffer(raw)
- doc, err := html.Parse(r)
-
- if err != nil {
- return err
- }
-
- if doc.FirstChild.Type != html.ElementNode ||
- doc.FirstChild.Data != "html" ||
- doc.FirstChild.FirstChild.NextSibling.Data != "body" {
- return errors.New("error parsing raw html")
- }
-
- body := doc.FirstChild.FirstChild.NextSibling
-
- report.addSection(command, body.FirstChild, nil)
-
- return nil
-}
-
-func (report *Report) addSection(command string, node *html.Node, section *Section) (*html.Node, *Section) {
- if node == nil ||
- node.Type != html.ElementNode ||
- node.Data != "h2" {
- return nil, nil
- }
-
- text, next := report.processNode(node)
- words := strings.Fields(text)
- lines := strings.Split(text, "\n")
-
- s := Section{
- Command: command,
- Name: node.FirstChild.Data,
- Text: text,
- Words: len(words),
- Lines: len(lines),
- }
-
- if section == nil {
- report.Report = append(report.Report, &s)
- return report.addSection(command, next, &s)
- }
-
- section.Sections = append(section.Sections, &s)
- return report.addSection(command, next, section)
-}
-
-func (report *Report) processNode(node *html.Node) (string, *html.Node) {
- text := ""
- current := node.NextSibling
-
- r := regexp.MustCompile(`<[^>]*>`)
-
- for current != nil {
- var buf bytes.Buffer
- w := io.Writer(&buf)
- html.Render(w, current)
-
- notags := r.ReplaceAllString(buf.String(), "")
- clean := strings.TrimSpace(notags)
-
- if text != "" && clean != "" {
- text = fmt.Sprintf("%s %s", text, clean)
- } else if clean != "" {
- text = clean
- }
-
- current = current.NextSibling
- if current == nil {
- return text, nil
- } else if current.Type == html.ElementNode &&
- current.Data == "h2" {
- node = current
- current = nil
- }
- }
-
- return text, node
-}
-
-// PerHeadline returns all sections across commands/pages with the same headline
-func (report *Report) PerHeadline(headline string) []Section {
- var results []Section
- for _, top := range report.Report {
- for _, section := range top.Sections {
- if section.Name != headline {
- continue
- }
-
- results = append(results, *section)
- }
- }
-
- return results
-}
diff --git a/vendor/github.com/smallstep/cli-utils/usage/usage.go b/vendor/github.com/smallstep/cli-utils/usage/usage.go
deleted file mode 100644
index 9ed88d9..0000000
--- a/vendor/github.com/smallstep/cli-utils/usage/usage.go
+++ /dev/null
@@ -1,214 +0,0 @@
-package usage
-
-import (
- "bytes"
- "fmt"
- "html"
- "strconv"
- "strings"
- "text/template"
-)
-
-var usageTextTempl = " {{.Name}}\n {{.Usage}} {{if .Required}}(Required){{else}}(Optional){{end}}{{if .Multiple}} (Multiple can be specified){{end}}\n"
-var templ *template.Template
-
-func init() {
- templ = template.Must(template.New("usageText").Parse(usageTextTempl))
-}
-
-// Argument specifies the Name, Usage, and whether or not an Argument is
-// required or not
-type Argument struct {
- Required bool
- Multiple bool
- Name string
- Usage string
-}
-
-// Decorate returns the name of an Argument and decorates it with notation to
-// indicate whether its required or not
-func (a Argument) Decorate() string {
- name := a.Name
- if a.Multiple {
- name += "(s)..."
- }
- if a.Required {
- return fmt.Sprintf("<%s>", name)
- }
-
- return fmt.Sprintf("[%s]", name)
-}
-
-// Arguments is an array of Argument structs that specify which arguments are
-// accepted by a Command
-type Arguments []Argument
-
-// UsageText returns the value of the UsageText property for a cli.Command for
-// these arguments
-func (args Arguments) UsageText() string {
- var buf bytes.Buffer
- for _, a := range args {
- data := map[string]interface{}{
- "Name": a.Decorate(),
- "Multiple": a.Multiple,
- "Required": a.Required,
- "Usage": a.Usage,
- }
-
- err := templ.Execute(&buf, data)
- if err != nil {
- panic(fmt.Sprintf("Could not generate args template for %s: %s", a.Name, err))
- }
- }
-
- return "\n\n" + buf.String()
-}
-
-// ArgsUsage returns the value of the ArgsUsage property for a cli.Command for
-// these arguments
-func (args Arguments) ArgsUsage() string {
- out := ""
- for i, a := range args {
- out += a.Decorate()
- if i < len(args)-1 {
- out += " "
- }
- }
-
- return out
-}
-
-// AppHelpTemplate contains the modified template for the main app
-var AppHelpTemplate = `## NAME
-**{{.HelpName}}** -- {{.Usage}}
-
-## USAGE
-{{if .UsageText}}{{.UsageText}}{{else}}**{{.HelpName}}**{{if .Commands}} <command>{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}_[arguments]_{{end}}{{end}}{{if .Description}}
-
-## DESCRIPTION
-{{.Description}}{{end}}{{if .VisibleCommands}}
-
-## COMMANDS
-
-{{range .VisibleCategories}}{{if .Name}}{{.Name}}:{{end}}
-|||
-|---|---|{{range .VisibleCommands}}
-| **{{join .Names ", "}}** | {{.Usage}} |{{end}}
-{{end}}{{if .VisibleFlags}}{{end}}
-
-## OPTIONS
-
-{{range $index, $option := .VisibleFlags}}{{if $index}}
-{{end}}{{$option}}
-{{end}}{{end}}{{if .Copyright}}{{if len .Authors}}
-
-## AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
-
-{{range $index, $author := .Authors}}{{if $index}}
-{{end}}{{$author}}{{end}}{{end}}{{if .Version}}{{if not .HideVersion}}
-
-## ONLINE
-
-This documentation is available online at https://smallstep.com/docs/cli
-
-## VERSION
-
-{{.Version}}{{end}}{{end}}
-
-## COPYRIGHT
-
-{{.Copyright}}
-
-## FEEDBACK ` +
- html.UnescapeString("&#"+strconv.Itoa(128525)+";") + " " +
- html.UnescapeString("&#"+strconv.Itoa(127867)+";") +
- `
-
-The **step** utility is not instrumented for usage statistics. It does not phone home.
-But your feedback is extremely valuable. Any information you can provide regarding how you’re using **step** helps.
-Please send us a sentence or two, good or bad: **feedback@smallstep.com** or ask in [GitHub Discussions](https://github.com/smallstep/certificates/discussions).
-{{end}}
-`
-
-// SubcommandHelpTemplate contains the modified template for a sub command
-// Note that the weird "|||\n|---|---|" syntax sets up a markdown table with empty headers.
-var SubcommandHelpTemplate = `## NAME
-**{{.HelpName}}** -- {{.Usage}}
-
-## USAGE
-
-{{if .UsageText}}{{.UsageText}}{{else}}**{{.HelpName}}** <command>{{if .VisibleFlags}} _[options]_{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}_[arguments]_{{end}}{{end}}{{if .Description}}
-
-## DESCRIPTION
-
-{{.Description}}{{end}}
-
-## COMMANDS
-
-{{range .VisibleCategories}}{{if .Name}}{{.Name}}:{{end}}
-|||
-|---|---|{{range .VisibleCommands}}
-| **{{join .Names ", "}}** | {{.Usage}} |{{end}}
-{{end}}{{if .VisibleFlags}}
-
-## OPTIONS
-
-{{range .VisibleFlags}}
-{{.}}
-{{end}}{{end}}
-`
-
-// CommandHelpTemplate contains the modified template for a command
-var CommandHelpTemplate = `## NAME
-**{{.HelpName}}** -- {{.Usage}}
-
-## USAGE
-
-{{if .UsageText}}{{.UsageText}}{{else}}**{{.HelpName}}**{{if .VisibleFlags}} _[options]_{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}_[arguments]_{{end}}{{end}}{{if .Category}}
-
-## CATEGORY
-
-{{.Category}}{{end}}{{if .Description}}
-
-## DESCRIPTION
-
-{{.Description}}{{end}}{{if .VisibleFlags}}
-
-## OPTIONS
-
-{{range .VisibleFlags}}
-{{.}}
-{{end}}{{end}}
-`
-
-// FlagNamePrefixer converts a full flag name and its placeholder into the help
-// message flag prefix. This is used by the default FlagStringer.
-//
-// This method clones urflave/cli functionality but adds a new line at the end.
-func FlagNamePrefixer(fullName, placeholder string) string {
- var prefixed string
- parts := strings.Split(fullName, ",")
- for i, name := range parts {
- name = strings.Trim(name, " ")
- prefixed += "**" + prefixFor(name) + name + "**"
-
- if placeholder != "" {
- prefixed += "=" + placeholder
- }
- if i < len(parts)-1 {
- prefixed += ", "
- }
- }
- //return "* " + prefixed + "\n"
- return prefixed + "\n: "
-}
-
-func prefixFor(name string) (prefix string) {
- if len(name) == 1 {
- prefix = "-"
- } else {
- prefix = "--"
- }
-
- return
-}
diff --git a/vendor/github.com/smallstep/nosql/postgresql/postgresql.go b/vendor/github.com/smallstep/nosql/postgresql/postgresql.go
index 67716c5..4109f99 100644
--- a/vendor/github.com/smallstep/nosql/postgresql/postgresql.go
+++ b/vendor/github.com/smallstep/nosql/postgresql/postgresql.go
@@ -10,8 +10,8 @@ import (
"fmt"
"strings"
- "github.com/jackc/pgx/v5"
- pgxstdlib "github.com/jackc/pgx/v5/stdlib"
+ "github.com/jackc/pgx/v4"
+ pgxstdlib "github.com/jackc/pgx/v4/stdlib"
"github.com/pkg/errors"
"github.com/smallstep/nosql/database"
)
diff --git a/vendor/github.com/smallstep/pkcs7/.gitignore b/vendor/github.com/smallstep/pkcs7/.gitignore
index 948aae2..daf913b 100644
--- a/vendor/github.com/smallstep/pkcs7/.gitignore
+++ b/vendor/github.com/smallstep/pkcs7/.gitignore
@@ -22,7 +22,3 @@ _testmain.go
*.exe
*.test
*.prof
-
-# Development
-.envrc
-coverage.out \ No newline at end of file
diff --git a/vendor/github.com/smallstep/pkcs7/README.md b/vendor/github.com/smallstep/pkcs7/README.md
index 9d94e65..a55d117 100644
--- a/vendor/github.com/smallstep/pkcs7/README.md
+++ b/vendor/github.com/smallstep/pkcs7/README.md
@@ -1,7 +1,7 @@
# pkcs7
-[![Go Reference](https://pkg.go.dev/badge/github.com/smallstep/pkcs7.svg)](https://pkg.go.dev/github.com/smallstep/pkcs7)
-[![Build Status](https://github.com/smallstep/pkcs7/workflows/CI/badge.svg?query=branch%3Amain+event%3Apush)](https://github.com/smallstep/pkcs7/actions/workflows/ci.yml?query=branch%3Amain+event%3Apush)
+[![GoDoc](https://godoc.org/go.mozilla.org/pkcs7?status.svg)](https://godoc.org/go.mozilla.org/pkcs7)
+[![Build Status](https://github.com/mozilla-services/pkcs7/workflows/CI/badge.svg?branch=master&event=push)](https://github.com/mozilla-services/pkcs7/actions/workflows/ci.yml?query=branch%3Amaster+event%3Apush)
pkcs7 implements parsing and creating signed and enveloped messages.
@@ -16,16 +16,18 @@ import (
"fmt"
"os"
- "github.com/smallstep/pkcs7"
+ "go.mozilla.org/pkcs7"
)
func SignAndDetach(content []byte, cert *x509.Certificate, privkey *rsa.PrivateKey) (signed []byte, err error) {
toBeSigned, err := NewSignedData(content)
if err != nil {
- return fmt.Errorf("Cannot initialize signed data: %w", err)
+ err = fmt.Errorf("Cannot initialize signed data: %s", err)
+ return
}
if err = toBeSigned.AddSigner(cert, privkey, SignerInfoConfig{}); err != nil {
- return fmt.Errorf("Cannot add signer: %w", err)
+ err = fmt.Errorf("Cannot add signer: %s", err)
+ return
}
// Detach signature, omit if you want an embedded signature
@@ -33,24 +35,28 @@ func SignAndDetach(content []byte, cert *x509.Certificate, privkey *rsa.PrivateK
signed, err = toBeSigned.Finish()
if err != nil {
- return fmt.Errorf("Cannot finish signing data: %w", err)
+ err = fmt.Errorf("Cannot finish signing data: %s", err)
+ return
}
// Verify the signature
pem.Encode(os.Stdout, &pem.Block{Type: "PKCS7", Bytes: signed})
p7, err := pkcs7.Parse(signed)
if err != nil {
- return fmt.Errorf("Cannot parse our signed data: %w", err)
+ err = fmt.Errorf("Cannot parse our signed data: %s", err)
+ return
}
// since the signature was detached, reattach the content here
p7.Content = content
if bytes.Compare(content, p7.Content) != 0 {
- return fmt.Errorf("Our content was not in the parsed data:\n\tExpected: %s\n\tActual: %s", content, p7.Content)
+ err = fmt.Errorf("Our content was not in the parsed data:\n\tExpected: %s\n\tActual: %s", content, p7.Content)
+ return
}
if err = p7.Verify(); err != nil {
- return fmt.Errorf("Cannot verify our signed data: %w", err)
+ err = fmt.Errorf("Cannot verify our signed data: %s", err)
+ return
}
return signed, nil
@@ -58,6 +64,6 @@ func SignAndDetach(content []byte, cert *x509.Certificate, privkey *rsa.PrivateK
```
-## Credits
-This is a fork of [mozilla-services/pkcs7](https://github.com/mozilla-services/pkcs7) which, itself, was a fork of [fullsailor/pkcs7](https://github.com/fullsailor/pkcs7).
+## Credits
+This is a fork of [fullsailor/pkcs7](https://github.com/fullsailor/pkcs7)
diff --git a/vendor/github.com/smallstep/pkcs7/ber.go b/vendor/github.com/smallstep/pkcs7/ber.go
index 5233321..73da024 100644
--- a/vendor/github.com/smallstep/pkcs7/ber.go
+++ b/vendor/github.com/smallstep/pkcs7/ber.go
@@ -5,6 +5,8 @@ import (
"errors"
)
+var encodeIndent = 0
+
type asn1Object interface {
EncodeTo(writer *bytes.Buffer) error
}
@@ -15,6 +17,8 @@ type asn1Structured struct {
}
func (s asn1Structured) EncodeTo(out *bytes.Buffer) error {
+ //fmt.Printf("%s--> tag: % X\n", strings.Repeat("| ", encodeIndent), s.tagBytes)
+ encodeIndent++
inner := new(bytes.Buffer)
for _, obj := range s.content {
err := obj.EncodeTo(inner)
@@ -22,6 +26,7 @@ func (s asn1Structured) EncodeTo(out *bytes.Buffer) error {
return err
}
}
+ encodeIndent--
out.Write(s.tagBytes)
encodeLength(out, inner.Len())
out.Write(inner.Bytes())
@@ -42,8 +47,8 @@ func (p asn1Primitive) EncodeTo(out *bytes.Buffer) error {
if err = encodeLength(out, p.length); err != nil {
return err
}
- // fmt.Printf("%s--> tag: % X length: %d\n", strings.Repeat("| ", encodeIndent), p.tagBytes, p.length)
- // fmt.Printf("%s--> content length: %d\n", strings.Repeat("| ", encodeIndent), len(p.content))
+ //fmt.Printf("%s--> tag: % X length: %d\n", strings.Repeat("| ", encodeIndent), p.tagBytes, p.length)
+ //fmt.Printf("%s--> content length: %d\n", strings.Repeat("| ", encodeIndent), len(p.content))
out.Write(p.content)
return nil
@@ -53,7 +58,7 @@ func ber2der(ber []byte) ([]byte, error) {
if len(ber) == 0 {
return nil, errors.New("ber2der: input ber is empty")
}
- // fmt.Printf("--> ber2der: Transcoding %d bytes\n", len(ber))
+ //fmt.Printf("--> ber2der: Transcoding %d bytes\n", len(ber))
out := new(bytes.Buffer)
obj, _, err := readObject(ber, 0)
@@ -64,7 +69,7 @@ func ber2der(ber []byte) ([]byte, error) {
// if offset < len(ber) {
// return nil, fmt.Errorf("ber2der: Content longer than expected. Got %d, expected %d", offset, len(ber))
- // }
+ //}
return out.Bytes(), nil
}
@@ -149,7 +154,7 @@ func readObject(ber []byte, offset int) (asn1Object, int, error) {
}
}
// jvehent 20170227: this doesn't appear to be used anywhere...
- // tag = tag*128 + ber[offset] - 0x80
+ //tag = tag*128 + ber[offset] - 0x80
offset++
if offset > berLen {
return nil, 0, errors.New("ber2der: cannot move offset forward, end of ber data reached")
@@ -199,7 +204,7 @@ func readObject(ber []byte, offset int) (asn1Object, int, error) {
if length < 0 {
return nil, 0, errors.New("ber2der: invalid negative value found in BER tag length")
}
- // fmt.Printf("--> length : %d\n", length)
+ //fmt.Printf("--> length : %d\n", length)
contentEnd := offset + length
if contentEnd > len(ber) {
return nil, 0, errors.New("ber2der: BER tag length is more than available data")
@@ -254,7 +259,7 @@ func readObject(ber []byte, offset int) (asn1Object, int, error) {
}
func isIndefiniteTermination(ber []byte, offset int) (bool, error) {
- if len(ber)-offset < 2 {
+ if len(ber) - offset < 2 {
return false, errors.New("ber2der: Invalid BER format")
}
@@ -262,5 +267,5 @@ func isIndefiniteTermination(ber []byte, offset int) (bool, error) {
}
func debugprint(format string, a ...interface{}) {
- // fmt.Printf(format, a)
+ //fmt.Printf(format, a)
}
diff --git a/vendor/github.com/smallstep/pkcs7/encrypt.go b/vendor/github.com/smallstep/pkcs7/encrypt.go
index a5c96e7..4c02e40 100644
--- a/vendor/github.com/smallstep/pkcs7/encrypt.go
+++ b/vendor/github.com/smallstep/pkcs7/encrypt.go
@@ -443,7 +443,8 @@ func EncryptUsingPSK(content []byte, key []byte) ([]byte, error) {
}
func marshalEncryptedContent(content []byte) asn1.RawValue {
- return asn1.RawValue{Bytes: content, Class: 2, IsCompound: false}
+ asn1Content, _ := asn1.Marshal(content)
+ return asn1.RawValue{Tag: 0, Class: 2, Bytes: asn1Content, IsCompound: true}
}
func encryptKey(key []byte, recipient *x509.Certificate, algorithm asn1.ObjectIdentifier, hash crypto.Hash) ([]byte, error) {
diff --git a/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/debug.go b/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/debug.go
deleted file mode 100644
index 378cc26..0000000
--- a/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/debug.go
+++ /dev/null
@@ -1,14 +0,0 @@
-package legacyx509
-
-import "fmt"
-
-// legacyGodebugSetting is a type mimicking Go's internal godebug package
-// settings, which are used to enable / disable certain functionalities at
-// build time.
-type legacyGodebugSetting int
-
-func (s legacyGodebugSetting) Value() string {
- return fmt.Sprintf("%d", s)
-}
-
-func (s legacyGodebugSetting) IncNonDefault() {}
diff --git a/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/doc.go b/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/doc.go
deleted file mode 100644
index 7d1469b..0000000
--- a/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/doc.go
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
-Package legacyx509 is a copy of certain parts of Go's crypto/x509 package.
-It is based on Go 1.23, and has just the parts copied over required for
-parsing X509 certificates.
-
-The primary reason this copy exists is to keep support for parsing PKCS7
-messages containing Simple Certificate Enrolment Protocol (SCEP) requests
-from Windows devices. Go 1.23 made a change marking certificates with a
-critical authority key identifier as invalid, which is mandated by RFC 5280,
-but apparently Windows marks those specific certificates as such, resulting
-in those SCEP requests failing from being parsed correctly.
-*/
-
-package legacyx509
diff --git a/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/oid.go b/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/oid.go
deleted file mode 100644
index 8268a07..0000000
--- a/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/oid.go
+++ /dev/null
@@ -1,377 +0,0 @@
-// Copyright 2023 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package legacyx509
-
-import (
- "bytes"
- "encoding/asn1"
- "errors"
- "math"
- "math/big"
- "math/bits"
- "strconv"
- "strings"
-)
-
-var (
- errInvalidOID = errors.New("invalid oid")
-)
-
-// An OID represents an ASN.1 OBJECT IDENTIFIER.
-type OID struct {
- der []byte
-}
-
-// ParseOID parses a Object Identifier string, represented by ASCII numbers separated by dots.
-func ParseOID(oid string) (OID, error) {
- var o OID
- return o, o.unmarshalOIDText(oid)
-}
-
-func newOIDFromDER(der []byte) (OID, bool) {
- if len(der) == 0 || der[len(der)-1]&0x80 != 0 {
- return OID{}, false
- }
-
- start := 0
- for i, v := range der {
- // ITU-T X.690, section 8.19.2:
- // The subidentifier shall be encoded in the fewest possible octets,
- // that is, the leading octet of the subidentifier shall not have the value 0x80.
- if i == start && v == 0x80 {
- return OID{}, false
- }
- if v&0x80 == 0 {
- start = i + 1
- }
- }
-
- return OID{der}, true
-}
-
-// OIDFromInts creates a new OID using ints, each integer is a separate component.
-func OIDFromInts(oid []uint64) (OID, error) {
- if len(oid) < 2 || oid[0] > 2 || (oid[0] < 2 && oid[1] >= 40) {
- return OID{}, errInvalidOID
- }
-
- length := base128IntLength(oid[0]*40 + oid[1])
- for _, v := range oid[2:] {
- length += base128IntLength(v)
- }
-
- der := make([]byte, 0, length)
- der = appendBase128Int(der, oid[0]*40+oid[1])
- for _, v := range oid[2:] {
- der = appendBase128Int(der, v)
- }
- return OID{der}, nil
-}
-
-func base128IntLength(n uint64) int {
- if n == 0 {
- return 1
- }
- return (bits.Len64(n) + 6) / 7
-}
-
-func appendBase128Int(dst []byte, n uint64) []byte {
- for i := base128IntLength(n) - 1; i >= 0; i-- {
- o := byte(n >> uint(i*7))
- o &= 0x7f
- if i != 0 {
- o |= 0x80
- }
- dst = append(dst, o)
- }
- return dst
-}
-
-func base128BigIntLength(n *big.Int) int {
- if n.Cmp(big.NewInt(0)) == 0 {
- return 1
- }
- return (n.BitLen() + 6) / 7
-}
-
-func appendBase128BigInt(dst []byte, n *big.Int) []byte {
- if n.Cmp(big.NewInt(0)) == 0 {
- return append(dst, 0)
- }
-
- for i := base128BigIntLength(n) - 1; i >= 0; i-- {
- o := byte(big.NewInt(0).Rsh(n, uint(i)*7).Bits()[0])
- o &= 0x7f
- if i != 0 {
- o |= 0x80
- }
- dst = append(dst, o)
- }
- return dst
-}
-
-// AppendText implements [encoding.TextAppender]
-func (o OID) AppendText(b []byte) ([]byte, error) {
- return append(b, o.String()...), nil
-}
-
-// MarshalText implements [encoding.TextMarshaler]
-func (o OID) MarshalText() ([]byte, error) {
- return o.AppendText(nil)
-}
-
-// UnmarshalText implements [encoding.TextUnmarshaler]
-func (o *OID) UnmarshalText(text []byte) error {
- return o.unmarshalOIDText(string(text))
-}
-
-// cutString slices s around the first instance of sep,
-// returning the text before and after sep.
-// The found result reports whether sep appears in s.
-// If sep does not appear in s, cut returns s, "", false.
-func cutString(s, sep string) (before, after string, found bool) {
- if i := strings.Index(s, sep); i >= 0 {
- return s[:i], s[i+len(sep):], true
- }
- return s, "", false
-}
-
-func (o *OID) unmarshalOIDText(oid string) error {
- // (*big.Int).SetString allows +/- signs, but we don't want
- // to allow them in the string representation of Object Identifier, so
- // reject such encodings.
- for _, c := range oid {
- isDigit := c >= '0' && c <= '9'
- if !isDigit && c != '.' {
- return errInvalidOID
- }
- }
-
- var (
- firstNum string
- secondNum string
- )
-
- var nextComponentExists bool
- firstNum, oid, nextComponentExists = cutString(oid, ".")
- if !nextComponentExists {
- return errInvalidOID
- }
- secondNum, oid, nextComponentExists = cutString(oid, ".")
-
- var (
- first = big.NewInt(0)
- second = big.NewInt(0)
- )
-
- if _, ok := first.SetString(firstNum, 10); !ok {
- return errInvalidOID
- }
- if _, ok := second.SetString(secondNum, 10); !ok {
- return errInvalidOID
- }
-
- if first.Cmp(big.NewInt(2)) > 0 || (first.Cmp(big.NewInt(2)) < 0 && second.Cmp(big.NewInt(40)) >= 0) {
- return errInvalidOID
- }
-
- firstComponent := first.Mul(first, big.NewInt(40))
- firstComponent.Add(firstComponent, second)
-
- der := appendBase128BigInt(make([]byte, 0, 32), firstComponent)
-
- for nextComponentExists {
- var strNum string
- strNum, oid, nextComponentExists = cutString(oid, ".")
- b, ok := big.NewInt(0).SetString(strNum, 10)
- if !ok {
- return errInvalidOID
- }
- der = appendBase128BigInt(der, b)
- }
-
- o.der = der
- return nil
-}
-
-// AppendBinary implements [encoding.BinaryAppender]
-func (o OID) AppendBinary(b []byte) ([]byte, error) {
- return append(b, o.der...), nil
-}
-
-// MarshalBinary implements [encoding.BinaryMarshaler]
-func (o OID) MarshalBinary() ([]byte, error) {
- return o.AppendBinary(nil)
-}
-
-// cloneBytes returns a copy of b[:len(b)].
-// The result may have additional unused capacity.
-// Clone(nil) returns nil.
-func cloneBytes(b []byte) []byte {
- if b == nil {
- return nil
- }
- return append([]byte{}, b...)
-}
-
-// UnmarshalBinary implements [encoding.BinaryUnmarshaler]
-func (o *OID) UnmarshalBinary(b []byte) error {
- oid, ok := newOIDFromDER(cloneBytes(b))
- if !ok {
- return errInvalidOID
- }
- *o = oid
- return nil
-}
-
-// Equal returns true when oid and other represents the same Object Identifier.
-func (oid OID) Equal(other OID) bool {
- // There is only one possible DER encoding of
- // each unique Object Identifier.
- return bytes.Equal(oid.der, other.der)
-}
-
-func parseBase128Int(bytes []byte, initOffset int) (ret, offset int, failed bool) {
- offset = initOffset
- var ret64 int64
- for shifted := 0; offset < len(bytes); shifted++ {
- // 5 * 7 bits per byte == 35 bits of data
- // Thus the representation is either non-minimal or too large for an int32
- if shifted == 5 {
- failed = true
- return
- }
- ret64 <<= 7
- b := bytes[offset]
- // integers should be minimally encoded, so the leading octet should
- // never be 0x80
- if shifted == 0 && b == 0x80 {
- failed = true
- return
- }
- ret64 |= int64(b & 0x7f)
- offset++
- if b&0x80 == 0 {
- ret = int(ret64)
- // Ensure that the returned value fits in an int on all platforms
- if ret64 > math.MaxInt32 {
- failed = true
- }
- return
- }
- }
- failed = true
- return
-}
-
-// EqualASN1OID returns whether an OID equals an asn1.ObjectIdentifier. If
-// asn1.ObjectIdentifier cannot represent the OID specified by oid, because
-// a component of OID requires more than 31 bits, it returns false.
-func (oid OID) EqualASN1OID(other asn1.ObjectIdentifier) bool {
- if len(other) < 2 {
- return false
- }
- v, offset, failed := parseBase128Int(oid.der, 0)
- if failed {
- // This should never happen, since we've already parsed the OID,
- // but just in case.
- return false
- }
- if v < 80 {
- a, b := v/40, v%40
- if other[0] != a || other[1] != b {
- return false
- }
- } else {
- a, b := 2, v-80
- if other[0] != a || other[1] != b {
- return false
- }
- }
-
- i := 2
- for ; offset < len(oid.der); i++ {
- v, offset, failed = parseBase128Int(oid.der, offset)
- if failed {
- // Again, shouldn't happen, since we've already parsed
- // the OID, but better safe than sorry.
- return false
- }
- if i >= len(other) || v != other[i] {
- return false
- }
- }
-
- return i == len(other)
-}
-
-// Strings returns the string representation of the Object Identifier.
-func (oid OID) String() string {
- var b strings.Builder
- b.Grow(32)
- const (
- valSize = 64 // size in bits of val.
- bitsPerByte = 7
- maxValSafeShift = (1 << (valSize - bitsPerByte)) - 1
- )
- var (
- start = 0
- val = uint64(0)
- numBuf = make([]byte, 0, 21)
- bigVal *big.Int
- overflow bool
- )
- for i, v := range oid.der {
- curVal := v & 0x7F
- valEnd := v&0x80 == 0
- if valEnd {
- if start != 0 {
- b.WriteByte('.')
- }
- }
- if !overflow && val > maxValSafeShift {
- if bigVal == nil {
- bigVal = new(big.Int)
- }
- bigVal = bigVal.SetUint64(val)
- overflow = true
- }
- if overflow {
- bigVal = bigVal.Lsh(bigVal, bitsPerByte).Or(bigVal, big.NewInt(int64(curVal)))
- if valEnd {
- if start == 0 {
- b.WriteString("2.")
- bigVal = bigVal.Sub(bigVal, big.NewInt(80))
- }
- numBuf = bigVal.Append(numBuf, 10)
- b.Write(numBuf)
- numBuf = numBuf[:0]
- val = 0
- start = i + 1
- overflow = false
- }
- continue
- }
- val <<= bitsPerByte
- val |= uint64(curVal)
- if valEnd {
- if start == 0 {
- if val < 80 {
- b.Write(strconv.AppendUint(numBuf, val/40, 10))
- b.WriteByte('.')
- b.Write(strconv.AppendUint(numBuf, val%40, 10))
- } else {
- b.WriteString("2.")
- b.Write(strconv.AppendUint(numBuf, val-80, 10))
- }
- } else {
- b.Write(strconv.AppendUint(numBuf, val, 10))
- }
- val = 0
- start = i + 1
- }
- }
- return b.String()
-}
diff --git a/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/parser.go b/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/parser.go
deleted file mode 100644
index ec57e79..0000000
--- a/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/parser.go
+++ /dev/null
@@ -1,1027 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package legacyx509
-
-import (
- "bytes"
- "crypto/dsa"
- "crypto/ecdsa"
- "crypto/ed25519"
- "crypto/elliptic"
- "crypto/rsa"
- "crypto/x509/pkix"
- "encoding/asn1"
- "errors"
- "fmt"
- "math/big"
- "net"
- "net/url"
- "strconv"
- "strings"
- "time"
- "unicode/utf16"
- "unicode/utf8"
-
- "golang.org/x/crypto/cryptobyte"
- cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1"
-
- stdx509 "crypto/x509"
-)
-
-// ParseCertificates parses one or more certificates from the given ASN.1 DER
-// data. The certificates must be concatenated with no intermediate padding.
-func ParseCertificates(der []byte) ([]*stdx509.Certificate, error) {
- var certs []*stdx509.Certificate
- for len(der) > 0 {
- cert, err := parseCertificate(der)
- if err != nil {
- return nil, err
- }
- certs = append(certs, cert)
- der = der[len(cert.Raw):]
- }
- return certs, nil
-}
-
-// isPrintable reports whether the given b is in the ASN.1 PrintableString set.
-// This is a simplified version of encoding/asn1.isPrintable.
-func isPrintable(b byte) bool {
- return 'a' <= b && b <= 'z' ||
- 'A' <= b && b <= 'Z' ||
- '0' <= b && b <= '9' ||
- '\'' <= b && b <= ')' ||
- '+' <= b && b <= '/' ||
- b == ' ' ||
- b == ':' ||
- b == '=' ||
- b == '?' ||
- // This is technically not allowed in a PrintableString.
- // However, x509 certificates with wildcard strings don't
- // always use the correct string type so we permit it.
- b == '*' ||
- // This is not technically allowed either. However, not
- // only is it relatively common, but there are also a
- // handful of CA certificates that contain it. At least
- // one of which will not expire until 2027.
- b == '&'
-}
-
-// parseASN1String parses the ASN.1 string types T61String, PrintableString,
-// UTF8String, BMPString, IA5String, and NumericString. This is mostly copied
-// from the respective encoding/asn1.parse... methods, rather than just
-// increasing the API surface of that package.
-func parseASN1String(tag cryptobyte_asn1.Tag, value []byte) (string, error) {
- switch tag {
- case cryptobyte_asn1.T61String:
- return string(value), nil
- case cryptobyte_asn1.PrintableString:
- for _, b := range value {
- if !isPrintable(b) {
- return "", errors.New("invalid PrintableString")
- }
- }
- return string(value), nil
- case cryptobyte_asn1.UTF8String:
- if !utf8.Valid(value) {
- return "", errors.New("invalid UTF-8 string")
- }
- return string(value), nil
- case cryptobyte_asn1.Tag(asn1.TagBMPString):
- if len(value)%2 != 0 {
- return "", errors.New("invalid BMPString")
- }
-
- // Strip terminator if present.
- if l := len(value); l >= 2 && value[l-1] == 0 && value[l-2] == 0 {
- value = value[:l-2]
- }
-
- s := make([]uint16, 0, len(value)/2)
- for len(value) > 0 {
- s = append(s, uint16(value[0])<<8+uint16(value[1]))
- value = value[2:]
- }
-
- return string(utf16.Decode(s)), nil
- case cryptobyte_asn1.IA5String:
- s := string(value)
- if isIA5String(s) != nil {
- return "", errors.New("invalid IA5String")
- }
- return s, nil
- case cryptobyte_asn1.Tag(asn1.TagNumericString):
- for _, b := range value {
- if !('0' <= b && b <= '9' || b == ' ') {
- return "", errors.New("invalid NumericString")
- }
- }
- return string(value), nil
- }
- return "", fmt.Errorf("unsupported string type: %v", tag)
-}
-
-// parseName parses a DER encoded Name as defined in RFC 5280. We may
-// want to export this function in the future for use in crypto/tls.
-func parseName(raw cryptobyte.String) (*pkix.RDNSequence, error) {
- if !raw.ReadASN1(&raw, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: invalid RDNSequence")
- }
-
- var rdnSeq pkix.RDNSequence
- for !raw.Empty() {
- var rdnSet pkix.RelativeDistinguishedNameSET
- var set cryptobyte.String
- if !raw.ReadASN1(&set, cryptobyte_asn1.SET) {
- return nil, errors.New("x509: invalid RDNSequence")
- }
- for !set.Empty() {
- var atav cryptobyte.String
- if !set.ReadASN1(&atav, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: invalid RDNSequence: invalid attribute")
- }
- var attr pkix.AttributeTypeAndValue
- if !atav.ReadASN1ObjectIdentifier(&attr.Type) {
- return nil, errors.New("x509: invalid RDNSequence: invalid attribute type")
- }
- var rawValue cryptobyte.String
- var valueTag cryptobyte_asn1.Tag
- if !atav.ReadAnyASN1(&rawValue, &valueTag) {
- return nil, errors.New("x509: invalid RDNSequence: invalid attribute value")
- }
- var err error
- attr.Value, err = parseASN1String(valueTag, rawValue)
- if err != nil {
- return nil, fmt.Errorf("x509: invalid RDNSequence: invalid attribute value: %s", err)
- }
- rdnSet = append(rdnSet, attr)
- }
-
- rdnSeq = append(rdnSeq, rdnSet)
- }
-
- return &rdnSeq, nil
-}
-
-func parseAI(der cryptobyte.String) (pkix.AlgorithmIdentifier, error) {
- ai := pkix.AlgorithmIdentifier{}
- if !der.ReadASN1ObjectIdentifier(&ai.Algorithm) {
- return ai, errors.New("x509: malformed OID")
- }
- if der.Empty() {
- return ai, nil
- }
- var params cryptobyte.String
- var tag cryptobyte_asn1.Tag
- if !der.ReadAnyASN1Element(&params, &tag) {
- return ai, errors.New("x509: malformed parameters")
- }
- ai.Parameters.Tag = int(tag)
- ai.Parameters.FullBytes = params
- return ai, nil
-}
-
-func parseTime(der *cryptobyte.String) (time.Time, error) {
- var t time.Time
- switch {
- case der.PeekASN1Tag(cryptobyte_asn1.UTCTime):
- if !der.ReadASN1UTCTime(&t) {
- return t, errors.New("x509: malformed UTCTime")
- }
- case der.PeekASN1Tag(cryptobyte_asn1.GeneralizedTime):
- if !der.ReadASN1GeneralizedTime(&t) {
- return t, errors.New("x509: malformed GeneralizedTime")
- }
- default:
- return t, errors.New("x509: unsupported time format")
- }
- return t, nil
-}
-
-func parseValidity(der cryptobyte.String) (time.Time, time.Time, error) {
- notBefore, err := parseTime(&der)
- if err != nil {
- return time.Time{}, time.Time{}, err
- }
- notAfter, err := parseTime(&der)
- if err != nil {
- return time.Time{}, time.Time{}, err
- }
-
- return notBefore, notAfter, nil
-}
-
-func parseExtension(der cryptobyte.String) (pkix.Extension, error) {
- var ext pkix.Extension
- if !der.ReadASN1ObjectIdentifier(&ext.Id) {
- return ext, errors.New("x509: malformed extension OID field")
- }
- if der.PeekASN1Tag(cryptobyte_asn1.BOOLEAN) {
- if !der.ReadASN1Boolean(&ext.Critical) {
- return ext, errors.New("x509: malformed extension critical field")
- }
- }
- var val cryptobyte.String
- if !der.ReadASN1(&val, cryptobyte_asn1.OCTET_STRING) {
- return ext, errors.New("x509: malformed extension value field")
- }
- ext.Value = val
- return ext, nil
-}
-
-func parsePublicKey(keyData *publicKeyInfo) (interface{}, error) {
- oid := keyData.Algorithm.Algorithm
- params := keyData.Algorithm.Parameters
- der := cryptobyte.String(keyData.PublicKey.RightAlign())
- switch {
- case oid.Equal(oidPublicKeyRSA):
- // RSA public keys must have a NULL in the parameters.
- // See RFC 3279, Section 2.3.1.
- if !bytes.Equal(params.FullBytes, asn1.NullBytes) {
- return nil, errors.New("x509: RSA key missing NULL parameters")
- }
-
- p := &pkcs1PublicKey{N: new(big.Int)}
- if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: invalid RSA public key")
- }
- if !der.ReadASN1Integer(p.N) {
- return nil, errors.New("x509: invalid RSA modulus")
- }
- if !der.ReadASN1Integer(&p.E) {
- return nil, errors.New("x509: invalid RSA public exponent")
- }
-
- if p.N.Sign() <= 0 {
- return nil, errors.New("x509: RSA modulus is not a positive number")
- }
- if p.E <= 0 {
- return nil, errors.New("x509: RSA public exponent is not a positive number")
- }
-
- pub := &rsa.PublicKey{
- E: p.E,
- N: p.N,
- }
- return pub, nil
- case oid.Equal(oidPublicKeyECDSA):
- paramsDer := cryptobyte.String(params.FullBytes)
- namedCurveOID := new(asn1.ObjectIdentifier)
- if !paramsDer.ReadASN1ObjectIdentifier(namedCurveOID) {
- return nil, errors.New("x509: invalid ECDSA parameters")
- }
- namedCurve := namedCurveFromOID(*namedCurveOID)
- if namedCurve == nil {
- return nil, errors.New("x509: unsupported elliptic curve")
- }
- x, y := elliptic.Unmarshal(namedCurve, der)
- if x == nil {
- return nil, errors.New("x509: failed to unmarshal elliptic curve point")
- }
- pub := &ecdsa.PublicKey{
- Curve: namedCurve,
- X: x,
- Y: y,
- }
- return pub, nil
- case oid.Equal(oidPublicKeyEd25519):
- // RFC 8410, Section 3
- // > For all of the OIDs, the parameters MUST be absent.
- if len(params.FullBytes) != 0 {
- return nil, errors.New("x509: Ed25519 key encoded with illegal parameters")
- }
- if len(der) != ed25519.PublicKeySize {
- return nil, errors.New("x509: wrong Ed25519 public key size")
- }
- return ed25519.PublicKey(der), nil
- // case oid.Equal(oidPublicKeyX25519):
- // // RFC 8410, Section 3
- // // > For all of the OIDs, the parameters MUST be absent.
- // if len(params.FullBytes) != 0 {
- // return nil, errors.New("x509: X25519 key encoded with illegal parameters")
- // }
- // return ecdh.X25519().NewPublicKey(der)
- case oid.Equal(oidPublicKeyDSA):
- y := new(big.Int)
- if !der.ReadASN1Integer(y) {
- return nil, errors.New("x509: invalid DSA public key")
- }
- pub := &dsa.PublicKey{
- Y: y,
- Parameters: dsa.Parameters{
- P: new(big.Int),
- Q: new(big.Int),
- G: new(big.Int),
- },
- }
- paramsDer := cryptobyte.String(params.FullBytes)
- if !paramsDer.ReadASN1(&paramsDer, cryptobyte_asn1.SEQUENCE) ||
- !paramsDer.ReadASN1Integer(pub.Parameters.P) ||
- !paramsDer.ReadASN1Integer(pub.Parameters.Q) ||
- !paramsDer.ReadASN1Integer(pub.Parameters.G) {
- return nil, errors.New("x509: invalid DSA parameters")
- }
- if pub.Y.Sign() <= 0 || pub.Parameters.P.Sign() <= 0 ||
- pub.Parameters.Q.Sign() <= 0 || pub.Parameters.G.Sign() <= 0 {
- return nil, errors.New("x509: zero or negative DSA parameter")
- }
- return pub, nil
- default:
- return nil, errors.New("x509: unknown public key algorithm")
- }
-}
-
-func parseKeyUsageExtension(der cryptobyte.String) (stdx509.KeyUsage, error) {
- var usageBits asn1.BitString
- if !der.ReadASN1BitString(&usageBits) {
- return 0, errors.New("x509: invalid key usage")
- }
-
- var usage int
- for i := 0; i < 9; i++ {
- if usageBits.At(i) != 0 {
- usage |= 1 << uint(i)
- }
- }
- return stdx509.KeyUsage(usage), nil
-}
-
-func parseBasicConstraintsExtension(der cryptobyte.String) (bool, int, error) {
- var isCA bool
- if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
- return false, 0, errors.New("x509: invalid basic constraints")
- }
- if der.PeekASN1Tag(cryptobyte_asn1.BOOLEAN) {
- if !der.ReadASN1Boolean(&isCA) {
- return false, 0, errors.New("x509: invalid basic constraints")
- }
- }
- maxPathLen := -1
- if der.PeekASN1Tag(cryptobyte_asn1.INTEGER) {
- if !der.ReadASN1Integer(&maxPathLen) {
- return false, 0, errors.New("x509: invalid basic constraints")
- }
- }
-
- // TODO: map out.MaxPathLen to 0 if it has the -1 default value? (Issue 19285)
- return isCA, maxPathLen, nil
-}
-
-func forEachSAN(der cryptobyte.String, callback func(tag int, data []byte) error) error {
- if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
- return errors.New("x509: invalid subject alternative names")
- }
- for !der.Empty() {
- var san cryptobyte.String
- var tag cryptobyte_asn1.Tag
- if !der.ReadAnyASN1(&san, &tag) {
- return errors.New("x509: invalid subject alternative name")
- }
- if err := callback(int(tag^0x80), san); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func parseSANExtension(der cryptobyte.String) (dnsNames, emailAddresses []string, ipAddresses []net.IP, uris []*url.URL, err error) {
- err = forEachSAN(der, func(tag int, data []byte) error {
- switch tag {
- case nameTypeEmail:
- email := string(data)
- if err := isIA5String(email); err != nil {
- return errors.New("x509: SAN rfc822Name is malformed")
- }
- emailAddresses = append(emailAddresses, email)
- case nameTypeDNS:
- name := string(data)
- if err := isIA5String(name); err != nil {
- return errors.New("x509: SAN dNSName is malformed")
- }
- dnsNames = append(dnsNames, string(name))
- case nameTypeURI:
- uriStr := string(data)
- if err := isIA5String(uriStr); err != nil {
- return errors.New("x509: SAN uniformResourceIdentifier is malformed")
- }
- uri, err := url.Parse(uriStr)
- if err != nil {
- return fmt.Errorf("x509: cannot parse URI %q: %s", uriStr, err)
- }
- if len(uri.Host) > 0 {
- if _, ok := domainToReverseLabels(uri.Host); !ok {
- return fmt.Errorf("x509: cannot parse URI %q: invalid domain", uriStr)
- }
- }
- uris = append(uris, uri)
- case nameTypeIP:
- switch len(data) {
- case net.IPv4len, net.IPv6len:
- ipAddresses = append(ipAddresses, data)
- default:
- return errors.New("x509: cannot parse IP address of length " + strconv.Itoa(len(data)))
- }
- }
-
- return nil
- })
-
- return
-}
-
-func parseAuthorityKeyIdentifier(e pkix.Extension) ([]byte, error) {
- // RFC 5280, Section 4.2.1.1
- // if e.Critical {
- // // Conforming CAs MUST mark this extension as non-critical
- // return nil, errors.New("x509: authority key identifier incorrectly marked critical")
- // }
- val := cryptobyte.String(e.Value)
- var akid cryptobyte.String
- if !val.ReadASN1(&akid, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: invalid authority key identifier")
- }
- if akid.PeekASN1Tag(cryptobyte_asn1.Tag(0).ContextSpecific()) {
- if !akid.ReadASN1(&akid, cryptobyte_asn1.Tag(0).ContextSpecific()) {
- return nil, errors.New("x509: invalid authority key identifier")
- }
- return akid, nil
- }
- return nil, nil
-}
-
-func parseExtKeyUsageExtension(der cryptobyte.String) ([]stdx509.ExtKeyUsage, []asn1.ObjectIdentifier, error) {
- var extKeyUsages []stdx509.ExtKeyUsage
- var unknownUsages []asn1.ObjectIdentifier
- if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
- return nil, nil, errors.New("x509: invalid extended key usages")
- }
- for !der.Empty() {
- var eku asn1.ObjectIdentifier
- if !der.ReadASN1ObjectIdentifier(&eku) {
- return nil, nil, errors.New("x509: invalid extended key usages")
- }
- if extKeyUsage, ok := extKeyUsageFromOID(eku); ok {
- extKeyUsages = append(extKeyUsages, stdx509.ExtKeyUsage(extKeyUsage))
- } else {
- unknownUsages = append(unknownUsages, eku)
- }
- }
- return extKeyUsages, unknownUsages, nil
-}
-
-// func parseCertificatePoliciesExtension(der cryptobyte.String) ([]OID, error) {
-// var oids []OID
-// if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
-// return nil, errors.New("x509: invalid certificate policies")
-// }
-// for !der.Empty() {
-// var cp cryptobyte.String
-// var OIDBytes cryptobyte.String
-// if !der.ReadASN1(&cp, cryptobyte_asn1.SEQUENCE) || !cp.ReadASN1(&OIDBytes, cryptobyte_asn1.OBJECT_IDENTIFIER) {
-// return nil, errors.New("x509: invalid certificate policies")
-// }
-// oid, ok := newOIDFromDER(OIDBytes)
-// if !ok {
-// return nil, errors.New("x509: invalid certificate policies")
-// }
-// oids = append(oids, oid)
-// }
-// return oids, nil
-// }
-
-// isValidIPMask reports whether mask consists of zero or more 1 bits, followed by zero bits.
-func isValidIPMask(mask []byte) bool {
- seenZero := false
-
- for _, b := range mask {
- if seenZero {
- if b != 0 {
- return false
- }
-
- continue
- }
-
- switch b {
- case 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe:
- seenZero = true
- case 0xff:
- default:
- return false
- }
- }
-
- return true
-}
-
-func parseNameConstraintsExtension(out *stdx509.Certificate, e pkix.Extension) (unhandled bool, err error) {
- // RFC 5280, 4.2.1.10
-
- // NameConstraints ::= SEQUENCE {
- // permittedSubtrees [0] GeneralSubtrees OPTIONAL,
- // excludedSubtrees [1] GeneralSubtrees OPTIONAL }
- //
- // GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
- //
- // GeneralSubtree ::= SEQUENCE {
- // base GeneralName,
- // minimum [0] BaseDistance DEFAULT 0,
- // maximum [1] BaseDistance OPTIONAL }
- //
- // BaseDistance ::= INTEGER (0..MAX)
-
- outer := cryptobyte.String(e.Value)
- var toplevel, permitted, excluded cryptobyte.String
- var havePermitted, haveExcluded bool
- if !outer.ReadASN1(&toplevel, cryptobyte_asn1.SEQUENCE) ||
- !outer.Empty() ||
- !toplevel.ReadOptionalASN1(&permitted, &havePermitted, cryptobyte_asn1.Tag(0).ContextSpecific().Constructed()) ||
- !toplevel.ReadOptionalASN1(&excluded, &haveExcluded, cryptobyte_asn1.Tag(1).ContextSpecific().Constructed()) ||
- !toplevel.Empty() {
- return false, errors.New("x509: invalid NameConstraints extension")
- }
-
- if !havePermitted && !haveExcluded || len(permitted) == 0 && len(excluded) == 0 {
- // From RFC 5280, Section 4.2.1.10:
- // “either the permittedSubtrees field
- // or the excludedSubtrees MUST be
- // present”
- return false, errors.New("x509: empty name constraints extension")
- }
-
- getValues := func(subtrees cryptobyte.String) (dnsNames []string, ips []*net.IPNet, emails, uriDomains []string, err error) {
- for !subtrees.Empty() {
- var seq, value cryptobyte.String
- var tag cryptobyte_asn1.Tag
- if !subtrees.ReadASN1(&seq, cryptobyte_asn1.SEQUENCE) ||
- !seq.ReadAnyASN1(&value, &tag) {
- return nil, nil, nil, nil, fmt.Errorf("x509: invalid NameConstraints extension")
- }
-
- var (
- dnsTag = cryptobyte_asn1.Tag(2).ContextSpecific()
- emailTag = cryptobyte_asn1.Tag(1).ContextSpecific()
- ipTag = cryptobyte_asn1.Tag(7).ContextSpecific()
- uriTag = cryptobyte_asn1.Tag(6).ContextSpecific()
- )
-
- switch tag {
- case dnsTag:
- domain := string(value)
- if err := isIA5String(domain); err != nil {
- return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + err.Error())
- }
-
- trimmedDomain := domain
- if len(trimmedDomain) > 0 && trimmedDomain[0] == '.' {
- // constraints can have a leading
- // period to exclude the domain
- // itself, but that's not valid in a
- // normal domain name.
- trimmedDomain = trimmedDomain[1:]
- }
- if _, ok := domainToReverseLabels(trimmedDomain); !ok {
- return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse dnsName constraint %q", domain)
- }
- dnsNames = append(dnsNames, domain)
-
- case ipTag:
- l := len(value)
- var ip, mask []byte
-
- switch l {
- case 8:
- ip = value[:4]
- mask = value[4:]
-
- case 32:
- ip = value[:16]
- mask = value[16:]
-
- default:
- return nil, nil, nil, nil, fmt.Errorf("x509: IP constraint contained value of length %d", l)
- }
-
- if !isValidIPMask(mask) {
- return nil, nil, nil, nil, fmt.Errorf("x509: IP constraint contained invalid mask %x", mask)
- }
-
- ips = append(ips, &net.IPNet{IP: net.IP(ip), Mask: net.IPMask(mask)})
-
- case emailTag:
- constraint := string(value)
- if err := isIA5String(constraint); err != nil {
- return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + err.Error())
- }
-
- // If the constraint contains an @ then
- // it specifies an exact mailbox name.
- if strings.Contains(constraint, "@") {
- if _, ok := parseRFC2821Mailbox(constraint); !ok {
- return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse rfc822Name constraint %q", constraint)
- }
- } else {
- // Otherwise it's a domain name.
- domain := constraint
- if len(domain) > 0 && domain[0] == '.' {
- domain = domain[1:]
- }
- if _, ok := domainToReverseLabels(domain); !ok {
- return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse rfc822Name constraint %q", constraint)
- }
- }
- emails = append(emails, constraint)
-
- case uriTag:
- domain := string(value)
- if err := isIA5String(domain); err != nil {
- return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + err.Error())
- }
-
- if net.ParseIP(domain) != nil {
- return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse URI constraint %q: cannot be IP address", domain)
- }
-
- trimmedDomain := domain
- if len(trimmedDomain) > 0 && trimmedDomain[0] == '.' {
- // constraints can have a leading
- // period to exclude the domain itself,
- // but that's not valid in a normal
- // domain name.
- trimmedDomain = trimmedDomain[1:]
- }
- if _, ok := domainToReverseLabels(trimmedDomain); !ok {
- return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse URI constraint %q", domain)
- }
- uriDomains = append(uriDomains, domain)
-
- default:
- unhandled = true
- }
- }
-
- return dnsNames, ips, emails, uriDomains, nil
- }
-
- if out.PermittedDNSDomains, out.PermittedIPRanges, out.PermittedEmailAddresses, out.PermittedURIDomains, err = getValues(permitted); err != nil {
- return false, err
- }
- if out.ExcludedDNSDomains, out.ExcludedIPRanges, out.ExcludedEmailAddresses, out.ExcludedURIDomains, err = getValues(excluded); err != nil {
- return false, err
- }
- out.PermittedDNSDomainsCritical = e.Critical
-
- return unhandled, nil
-}
-
-func processExtensions(out *stdx509.Certificate) error {
- var err error
- for _, e := range out.Extensions {
- unhandled := false
-
- if len(e.Id) == 4 && e.Id[0] == 2 && e.Id[1] == 5 && e.Id[2] == 29 {
- switch e.Id[3] {
- case 15:
- out.KeyUsage, err = parseKeyUsageExtension(e.Value)
- if err != nil {
- return err
- }
- case 19:
- out.IsCA, out.MaxPathLen, err = parseBasicConstraintsExtension(e.Value)
- if err != nil {
- return err
- }
- out.BasicConstraintsValid = true
- out.MaxPathLenZero = out.MaxPathLen == 0
- case 17:
- out.DNSNames, out.EmailAddresses, out.IPAddresses, out.URIs, err = parseSANExtension(e.Value)
- if err != nil {
- return err
- }
-
- if len(out.DNSNames) == 0 && len(out.EmailAddresses) == 0 && len(out.IPAddresses) == 0 && len(out.URIs) == 0 {
- // If we didn't parse anything then we do the critical check, below.
- unhandled = true
- }
-
- case 30:
- unhandled, err = parseNameConstraintsExtension(out, e)
- if err != nil {
- return err
- }
-
- case 31:
- // RFC 5280, 4.2.1.13
-
- // CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
- //
- // DistributionPoint ::= SEQUENCE {
- // distributionPoint [0] DistributionPointName OPTIONAL,
- // reasons [1] ReasonFlags OPTIONAL,
- // cRLIssuer [2] GeneralNames OPTIONAL }
- //
- // DistributionPointName ::= CHOICE {
- // fullName [0] GeneralNames,
- // nameRelativeToCRLIssuer [1] RelativeDistinguishedName }
- val := cryptobyte.String(e.Value)
- if !val.ReadASN1(&val, cryptobyte_asn1.SEQUENCE) {
- return errors.New("x509: invalid CRL distribution points")
- }
- for !val.Empty() {
- var dpDER cryptobyte.String
- if !val.ReadASN1(&dpDER, cryptobyte_asn1.SEQUENCE) {
- return errors.New("x509: invalid CRL distribution point")
- }
- var dpNameDER cryptobyte.String
- var dpNamePresent bool
- if !dpDER.ReadOptionalASN1(&dpNameDER, &dpNamePresent, cryptobyte_asn1.Tag(0).Constructed().ContextSpecific()) {
- return errors.New("x509: invalid CRL distribution point")
- }
- if !dpNamePresent {
- continue
- }
- if !dpNameDER.ReadASN1(&dpNameDER, cryptobyte_asn1.Tag(0).Constructed().ContextSpecific()) {
- return errors.New("x509: invalid CRL distribution point")
- }
- for !dpNameDER.Empty() {
- if !dpNameDER.PeekASN1Tag(cryptobyte_asn1.Tag(6).ContextSpecific()) {
- break
- }
- var uri cryptobyte.String
- if !dpNameDER.ReadASN1(&uri, cryptobyte_asn1.Tag(6).ContextSpecific()) {
- return errors.New("x509: invalid CRL distribution point")
- }
- out.CRLDistributionPoints = append(out.CRLDistributionPoints, string(uri))
- }
- }
-
- case 35:
- out.AuthorityKeyId, err = parseAuthorityKeyIdentifier(e)
- if err != nil {
- return err
- }
- case 37:
- out.ExtKeyUsage, out.UnknownExtKeyUsage, err = parseExtKeyUsageExtension(e.Value)
- if err != nil {
- return err
- }
- case 14:
- // RFC 5280, 4.2.1.2
- if e.Critical {
- // Conforming CAs MUST mark this extension as non-critical
- return errors.New("x509: subject key identifier incorrectly marked critical")
- }
- val := cryptobyte.String(e.Value)
- var skid cryptobyte.String
- if !val.ReadASN1(&skid, cryptobyte_asn1.OCTET_STRING) {
- return errors.New("x509: invalid subject key identifier")
- }
- out.SubjectKeyId = skid
- // case 32:
- // out.Policies, err = parseCertificatePoliciesExtension(e.Value)
- // if err != nil {
- // return err
- // }
- // out.PolicyIdentifiers = make([]asn1.ObjectIdentifier, 0, len(out.Policies))
- // for _, oid := range out.Policies {
- // if oid, ok := oid.toASN1OID(); ok {
- // out.PolicyIdentifiers = append(out.PolicyIdentifiers, oid)
- // }
- // }
- default:
- // Unknown extensions are recorded if critical.
- unhandled = true
- }
- } else if e.Id.Equal(oidExtensionAuthorityInfoAccess) {
- // RFC 5280 4.2.2.1: Authority Information Access
- if e.Critical {
- // Conforming CAs MUST mark this extension as non-critical
- return errors.New("x509: authority info access incorrectly marked critical")
- }
- val := cryptobyte.String(e.Value)
- if !val.ReadASN1(&val, cryptobyte_asn1.SEQUENCE) {
- return errors.New("x509: invalid authority info access")
- }
- for !val.Empty() {
- var aiaDER cryptobyte.String
- if !val.ReadASN1(&aiaDER, cryptobyte_asn1.SEQUENCE) {
- return errors.New("x509: invalid authority info access")
- }
- var method asn1.ObjectIdentifier
- if !aiaDER.ReadASN1ObjectIdentifier(&method) {
- return errors.New("x509: invalid authority info access")
- }
- if !aiaDER.PeekASN1Tag(cryptobyte_asn1.Tag(6).ContextSpecific()) {
- continue
- }
- if !aiaDER.ReadASN1(&aiaDER, cryptobyte_asn1.Tag(6).ContextSpecific()) {
- return errors.New("x509: invalid authority info access")
- }
- switch {
- case method.Equal(oidAuthorityInfoAccessOcsp):
- out.OCSPServer = append(out.OCSPServer, string(aiaDER))
- case method.Equal(oidAuthorityInfoAccessIssuers):
- out.IssuingCertificateURL = append(out.IssuingCertificateURL, string(aiaDER))
- }
- }
- } else {
- // Unknown extensions are recorded if critical.
- unhandled = true
- }
-
- if e.Critical && unhandled {
- out.UnhandledCriticalExtensions = append(out.UnhandledCriticalExtensions, e.Id)
- }
- }
-
- return nil
-}
-
-var x509negativeserial = legacyGodebugSetting(0) // replaces godebug.New("x509negativeserial")
-
-func parseCertificate(der []byte) (*stdx509.Certificate, error) {
- cert := &stdx509.Certificate{}
-
- input := cryptobyte.String(der)
- // we read the SEQUENCE including length and tag bytes so that
- // we can populate Certificate.Raw, before unwrapping the
- // SEQUENCE so it can be operated on
- if !input.ReadASN1Element(&input, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed certificate")
- }
- cert.Raw = input
- if !input.ReadASN1(&input, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed certificate")
- }
-
- var tbs cryptobyte.String
- // do the same trick again as above to extract the raw
- // bytes for Certificate.RawTBSCertificate
- if !input.ReadASN1Element(&tbs, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed tbs certificate")
- }
- cert.RawTBSCertificate = tbs
- if !tbs.ReadASN1(&tbs, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed tbs certificate")
- }
-
- if !tbs.ReadOptionalASN1Integer(&cert.Version, cryptobyte_asn1.Tag(0).Constructed().ContextSpecific(), 0) {
- return nil, errors.New("x509: malformed version")
- }
- if cert.Version < 0 {
- return nil, errors.New("x509: malformed version")
- }
- // for backwards compat reasons Version is one-indexed,
- // rather than zero-indexed as defined in 5280
- cert.Version++
- if cert.Version > 3 {
- return nil, errors.New("x509: invalid version")
- }
-
- serial := new(big.Int)
- if !tbs.ReadASN1Integer(serial) {
- return nil, errors.New("x509: malformed serial number")
- }
- if serial.Sign() == -1 {
- if x509negativeserial.Value() != "1" {
- return nil, errors.New("x509: negative serial number")
- } else {
- x509negativeserial.IncNonDefault()
- }
- }
- cert.SerialNumber = serial
-
- var sigAISeq cryptobyte.String
- if !tbs.ReadASN1(&sigAISeq, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed signature algorithm identifier")
- }
- // Before parsing the inner algorithm identifier, extract
- // the outer algorithm identifier and make sure that they
- // match.
- var outerSigAISeq cryptobyte.String
- if !input.ReadASN1(&outerSigAISeq, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed algorithm identifier")
- }
- if !bytes.Equal(outerSigAISeq, sigAISeq) {
- return nil, errors.New("x509: inner and outer signature algorithm identifiers don't match")
- }
- sigAI, err := parseAI(sigAISeq)
- if err != nil {
- return nil, err
- }
- cert.SignatureAlgorithm = getSignatureAlgorithmFromAI(sigAI)
-
- var issuerSeq cryptobyte.String
- if !tbs.ReadASN1Element(&issuerSeq, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed issuer")
- }
- cert.RawIssuer = issuerSeq
- issuerRDNs, err := parseName(issuerSeq)
- if err != nil {
- return nil, err
- }
- cert.Issuer.FillFromRDNSequence(issuerRDNs)
-
- var validity cryptobyte.String
- if !tbs.ReadASN1(&validity, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed validity")
- }
- cert.NotBefore, cert.NotAfter, err = parseValidity(validity)
- if err != nil {
- return nil, err
- }
-
- var subjectSeq cryptobyte.String
- if !tbs.ReadASN1Element(&subjectSeq, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed issuer")
- }
- cert.RawSubject = subjectSeq
- subjectRDNs, err := parseName(subjectSeq)
- if err != nil {
- return nil, err
- }
- cert.Subject.FillFromRDNSequence(subjectRDNs)
-
- var spki cryptobyte.String
- if !tbs.ReadASN1Element(&spki, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed spki")
- }
- cert.RawSubjectPublicKeyInfo = spki
- if !spki.ReadASN1(&spki, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed spki")
- }
- var pkAISeq cryptobyte.String
- if !spki.ReadASN1(&pkAISeq, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed public key algorithm identifier")
- }
- pkAI, err := parseAI(pkAISeq)
- if err != nil {
- return nil, err
- }
- cert.PublicKeyAlgorithm = getPublicKeyAlgorithmFromOID(pkAI.Algorithm)
- var spk asn1.BitString
- if !spki.ReadASN1BitString(&spk) {
- return nil, errors.New("x509: malformed subjectPublicKey")
- }
- if cert.PublicKeyAlgorithm != stdx509.UnknownPublicKeyAlgorithm {
- cert.PublicKey, err = parsePublicKey(&publicKeyInfo{
- Algorithm: pkAI,
- PublicKey: spk,
- })
- if err != nil {
- return nil, err
- }
- }
-
- if cert.Version > 1 {
- if !tbs.SkipOptionalASN1(cryptobyte_asn1.Tag(1).ContextSpecific()) {
- return nil, errors.New("x509: malformed issuerUniqueID")
- }
- if !tbs.SkipOptionalASN1(cryptobyte_asn1.Tag(2).ContextSpecific()) {
- return nil, errors.New("x509: malformed subjectUniqueID")
- }
- if cert.Version == 3 {
- var extensions cryptobyte.String
- var present bool
- if !tbs.ReadOptionalASN1(&extensions, &present, cryptobyte_asn1.Tag(3).Constructed().ContextSpecific()) {
- return nil, errors.New("x509: malformed extensions")
- }
- if present {
- seenExts := make(map[string]bool)
- if !extensions.ReadASN1(&extensions, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed extensions")
- }
- for !extensions.Empty() {
- var extension cryptobyte.String
- if !extensions.ReadASN1(&extension, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed extension")
- }
- ext, err := parseExtension(extension)
- if err != nil {
- return nil, err
- }
- oidStr := ext.Id.String()
- if seenExts[oidStr] {
- return nil, fmt.Errorf("x509: certificate contains duplicate extension with OID %q", oidStr)
- }
- seenExts[oidStr] = true
- cert.Extensions = append(cert.Extensions, ext)
- }
- err = processExtensions(cert)
- if err != nil {
- return nil, err
- }
- }
- }
- }
-
- var signature asn1.BitString
- if !input.ReadASN1BitString(&signature) {
- return nil, errors.New("x509: malformed signature")
- }
- cert.Signature = signature.RightAlign()
-
- return cert, nil
-}
diff --git a/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/pkcs1.go b/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/pkcs1.go
deleted file mode 100644
index da3c38a..0000000
--- a/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/pkcs1.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package legacyx509
-
-import (
- "math/big"
-)
-
-// pkcs1PublicKey reflects the ASN.1 structure of a PKCS #1 public key.
-type pkcs1PublicKey struct {
- N *big.Int
- E int
-}
diff --git a/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/verify.go b/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/verify.go
deleted file mode 100644
index 901e3ba..0000000
--- a/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/verify.go
+++ /dev/null
@@ -1,193 +0,0 @@
-package legacyx509
-
-import (
- "bytes"
- "strings"
-)
-
-// rfc2821Mailbox represents a “mailbox” (which is an email address to most
-// people) by breaking it into the “local” (i.e. before the '@') and “domain”
-// parts.
-type rfc2821Mailbox struct {
- local, domain string
-}
-
-// parseRFC2821Mailbox parses an email address into local and domain parts,
-// based on the ABNF for a “Mailbox” from RFC 2821. According to RFC 5280,
-// Section 4.2.1.6 that's correct for an rfc822Name from a certificate: “The
-// format of an rfc822Name is a "Mailbox" as defined in RFC 2821, Section 4.1.2”.
-func parseRFC2821Mailbox(in string) (mailbox rfc2821Mailbox, ok bool) {
- if len(in) == 0 {
- return mailbox, false
- }
-
- localPartBytes := make([]byte, 0, len(in)/2)
-
- if in[0] == '"' {
- // Quoted-string = DQUOTE *qcontent DQUOTE
- // non-whitespace-control = %d1-8 / %d11 / %d12 / %d14-31 / %d127
- // qcontent = qtext / quoted-pair
- // qtext = non-whitespace-control /
- // %d33 / %d35-91 / %d93-126
- // quoted-pair = ("\" text) / obs-qp
- // text = %d1-9 / %d11 / %d12 / %d14-127 / obs-text
- //
- // (Names beginning with “obs-” are the obsolete syntax from RFC 2822,
- // Section 4. Since it has been 16 years, we no longer accept that.)
- in = in[1:]
- QuotedString:
- for {
- if len(in) == 0 {
- return mailbox, false
- }
- c := in[0]
- in = in[1:]
-
- switch {
- case c == '"':
- break QuotedString
-
- case c == '\\':
- // quoted-pair
- if len(in) == 0 {
- return mailbox, false
- }
- if in[0] == 11 ||
- in[0] == 12 ||
- (1 <= in[0] && in[0] <= 9) ||
- (14 <= in[0] && in[0] <= 127) {
- localPartBytes = append(localPartBytes, in[0])
- in = in[1:]
- } else {
- return mailbox, false
- }
-
- case c == 11 ||
- c == 12 ||
- // Space (char 32) is not allowed based on the
- // BNF, but RFC 3696 gives an example that
- // assumes that it is. Several “verified”
- // errata continue to argue about this point.
- // We choose to accept it.
- c == 32 ||
- c == 33 ||
- c == 127 ||
- (1 <= c && c <= 8) ||
- (14 <= c && c <= 31) ||
- (35 <= c && c <= 91) ||
- (93 <= c && c <= 126):
- // qtext
- localPartBytes = append(localPartBytes, c)
-
- default:
- return mailbox, false
- }
- }
- } else {
- // Atom ("." Atom)*
- NextChar:
- for len(in) > 0 {
- // atext from RFC 2822, Section 3.2.4
- c := in[0]
-
- switch {
- case c == '\\':
- // Examples given in RFC 3696 suggest that
- // escaped characters can appear outside of a
- // quoted string. Several “verified” errata
- // continue to argue the point. We choose to
- // accept it.
- in = in[1:]
- if len(in) == 0 {
- return mailbox, false
- }
- fallthrough
-
- case ('0' <= c && c <= '9') ||
- ('a' <= c && c <= 'z') ||
- ('A' <= c && c <= 'Z') ||
- c == '!' || c == '#' || c == '$' || c == '%' ||
- c == '&' || c == '\'' || c == '*' || c == '+' ||
- c == '-' || c == '/' || c == '=' || c == '?' ||
- c == '^' || c == '_' || c == '`' || c == '{' ||
- c == '|' || c == '}' || c == '~' || c == '.':
- localPartBytes = append(localPartBytes, in[0])
- in = in[1:]
-
- default:
- break NextChar
- }
- }
-
- if len(localPartBytes) == 0 {
- return mailbox, false
- }
-
- // From RFC 3696, Section 3:
- // “period (".") may also appear, but may not be used to start
- // or end the local part, nor may two or more consecutive
- // periods appear.”
- twoDots := []byte{'.', '.'}
- if localPartBytes[0] == '.' ||
- localPartBytes[len(localPartBytes)-1] == '.' ||
- bytes.Contains(localPartBytes, twoDots) {
- return mailbox, false
- }
- }
-
- if len(in) == 0 || in[0] != '@' {
- return mailbox, false
- }
- in = in[1:]
-
- // The RFC species a format for domains, but that's known to be
- // violated in practice so we accept that anything after an '@' is the
- // domain part.
- if _, ok := domainToReverseLabels(in); !ok {
- return mailbox, false
- }
-
- mailbox.local = string(localPartBytes)
- mailbox.domain = in
- return mailbox, true
-}
-
-// domainToReverseLabels converts a textual domain name like foo.example.com to
-// the list of labels in reverse order, e.g. ["com", "example", "foo"].
-func domainToReverseLabels(domain string) (reverseLabels []string, ok bool) {
- for len(domain) > 0 {
- if i := strings.LastIndexByte(domain, '.'); i == -1 {
- reverseLabels = append(reverseLabels, domain)
- domain = ""
- } else {
- reverseLabels = append(reverseLabels, domain[i+1:])
- domain = domain[:i]
- if i == 0 { // domain == ""
- // domain is prefixed with an empty label, append an empty
- // string to reverseLabels to indicate this.
- reverseLabels = append(reverseLabels, "")
- }
- }
- }
-
- if len(reverseLabels) > 0 && len(reverseLabels[0]) == 0 {
- // An empty label at the end indicates an absolute value.
- return nil, false
- }
-
- for _, label := range reverseLabels {
- if len(label) == 0 {
- // Empty labels are otherwise invalid.
- return nil, false
- }
-
- for _, c := range label {
- if c < 33 || c > 126 {
- // Invalid character.
- return nil, false
- }
- }
- }
-
- return reverseLabels, true
-}
diff --git a/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/x509.go b/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/x509.go
deleted file mode 100644
index a4500bf..0000000
--- a/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/x509.go
+++ /dev/null
@@ -1,488 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package x509 implements a subset of the X.509 standard.
-//
-// It allows parsing and generating certificates, certificate signing
-// requests, certificate revocation lists, and encoded public and private keys.
-// It provides a certificate verifier, complete with a chain builder.
-//
-// The package targets the X.509 technical profile defined by the IETF (RFC
-// 2459/3280/5280), and as further restricted by the CA/Browser Forum Baseline
-// Requirements. There is minimal support for features outside of these
-// profiles, as the primary goal of the package is to provide compatibility
-// with the publicly trusted TLS certificate ecosystem and its policies and
-// constraints.
-//
-// On macOS and Windows, certificate verification is handled by system APIs, but
-// the package aims to apply consistent validation rules across operating
-// systems.
-package legacyx509
-
-import (
- "bytes"
- "crypto"
- "crypto/elliptic"
- stdx509 "crypto/x509"
- "crypto/x509/pkix"
- "encoding/asn1"
- "fmt"
- "strconv"
- "unicode"
-
- // Explicitly import these for their crypto.RegisterHash init side-effects.
- // Keep these as blank imports, even if they're imported above.
- _ "crypto/sha1"
- _ "crypto/sha256"
- _ "crypto/sha512"
-)
-
-type publicKeyInfo struct {
- Raw asn1.RawContent
- Algorithm pkix.AlgorithmIdentifier
- PublicKey asn1.BitString
-}
-
-type SignatureAlgorithm int
-
-const (
- UnknownSignatureAlgorithm SignatureAlgorithm = iota
-
- MD2WithRSA // Unsupported.
- MD5WithRSA // Only supported for signing, not verification.
- SHA1WithRSA // Only supported for signing, and verification of CRLs, CSRs, and OCSP responses.
- SHA256WithRSA
- SHA384WithRSA
- SHA512WithRSA
- DSAWithSHA1 // Unsupported.
- DSAWithSHA256 // Unsupported.
- ECDSAWithSHA1 // Only supported for signing, and verification of CRLs, CSRs, and OCSP responses.
- ECDSAWithSHA256
- ECDSAWithSHA384
- ECDSAWithSHA512
- SHA256WithRSAPSS
- SHA384WithRSAPSS
- SHA512WithRSAPSS
- PureEd25519
-)
-
-func (algo SignatureAlgorithm) String() string {
- for _, details := range signatureAlgorithmDetails {
- if details.algo == algo {
- return details.name
- }
- }
- return strconv.Itoa(int(algo))
-}
-
-type PublicKeyAlgorithm int
-
-const (
- UnknownPublicKeyAlgorithm PublicKeyAlgorithm = iota
- RSA
- DSA // Only supported for parsing.
- ECDSA
- Ed25519
-)
-
-var publicKeyAlgoName = [...]string{
- RSA: "RSA",
- DSA: "DSA",
- ECDSA: "ECDSA",
- Ed25519: "Ed25519",
-}
-
-func (algo PublicKeyAlgorithm) String() string {
- if 0 < algo && int(algo) < len(publicKeyAlgoName) {
- return publicKeyAlgoName[algo]
- }
- return strconv.Itoa(int(algo))
-}
-
-// OIDs for signature algorithms
-//
-// pkcs-1 OBJECT IDENTIFIER ::= {
-// iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 }
-//
-// RFC 3279 2.2.1 RSA Signature Algorithms
-//
-// md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 }
-//
-// sha-1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 }
-//
-// dsaWithSha1 OBJECT IDENTIFIER ::= {
-// iso(1) member-body(2) us(840) x9-57(10040) x9cm(4) 3 }
-//
-// RFC 3279 2.2.3 ECDSA Signature Algorithm
-//
-// ecdsa-with-SHA1 OBJECT IDENTIFIER ::= {
-// iso(1) member-body(2) us(840) ansi-x962(10045)
-// signatures(4) ecdsa-with-SHA1(1)}
-//
-// RFC 4055 5 PKCS #1 Version 1.5
-//
-// sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 }
-//
-// sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 }
-//
-// sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 }
-//
-// RFC 5758 3.1 DSA Signature Algorithms
-//
-// dsaWithSha256 OBJECT IDENTIFIER ::= {
-// joint-iso-ccitt(2) country(16) us(840) organization(1) gov(101)
-// csor(3) algorithms(4) id-dsa-with-sha2(3) 2}
-//
-// RFC 5758 3.2 ECDSA Signature Algorithm
-//
-// ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
-// us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 }
-//
-// ecdsa-with-SHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
-// us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 3 }
-//
-// ecdsa-with-SHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
-// us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 4 }
-//
-// RFC 8410 3 Curve25519 and Curve448 Algorithm Identifiers
-//
-// id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 }
-var (
- oidSignatureMD5WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 4}
- oidSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}
- oidSignatureSHA256WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11}
- oidSignatureSHA384WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12}
- oidSignatureSHA512WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13}
- oidSignatureRSAPSS = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 10}
- oidSignatureDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 3}
- oidSignatureDSAWithSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 2}
- oidSignatureECDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 1}
- oidSignatureECDSAWithSHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2}
- oidSignatureECDSAWithSHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3}
- oidSignatureECDSAWithSHA512 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 4}
- oidSignatureEd25519 = asn1.ObjectIdentifier{1, 3, 101, 112}
-
- oidSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1}
- oidSHA384 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 2}
- oidSHA512 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 3}
-
- oidMGF1 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 8}
-
- // oidISOSignatureSHA1WithRSA means the same as oidSignatureSHA1WithRSA
- // but it's specified by ISO. Microsoft's makecert.exe has been known
- // to produce certificates with this OID.
- oidISOSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 29}
-)
-
-var signatureAlgorithmDetails = []struct {
- algo SignatureAlgorithm
- name string
- oid asn1.ObjectIdentifier
- params asn1.RawValue
- pubKeyAlgo PublicKeyAlgorithm
- hash crypto.Hash
- isRSAPSS bool
-}{
- {MD5WithRSA, "MD5-RSA", oidSignatureMD5WithRSA, asn1.NullRawValue, RSA, crypto.MD5, false},
- {SHA1WithRSA, "SHA1-RSA", oidSignatureSHA1WithRSA, asn1.NullRawValue, RSA, crypto.SHA1, false},
- {SHA1WithRSA, "SHA1-RSA", oidISOSignatureSHA1WithRSA, asn1.NullRawValue, RSA, crypto.SHA1, false},
- {SHA256WithRSA, "SHA256-RSA", oidSignatureSHA256WithRSA, asn1.NullRawValue, RSA, crypto.SHA256, false},
- {SHA384WithRSA, "SHA384-RSA", oidSignatureSHA384WithRSA, asn1.NullRawValue, RSA, crypto.SHA384, false},
- {SHA512WithRSA, "SHA512-RSA", oidSignatureSHA512WithRSA, asn1.NullRawValue, RSA, crypto.SHA512, false},
- {SHA256WithRSAPSS, "SHA256-RSAPSS", oidSignatureRSAPSS, pssParametersSHA256, RSA, crypto.SHA256, true},
- {SHA384WithRSAPSS, "SHA384-RSAPSS", oidSignatureRSAPSS, pssParametersSHA384, RSA, crypto.SHA384, true},
- {SHA512WithRSAPSS, "SHA512-RSAPSS", oidSignatureRSAPSS, pssParametersSHA512, RSA, crypto.SHA512, true},
- {DSAWithSHA1, "DSA-SHA1", oidSignatureDSAWithSHA1, emptyRawValue, DSA, crypto.SHA1, false},
- {DSAWithSHA256, "DSA-SHA256", oidSignatureDSAWithSHA256, emptyRawValue, DSA, crypto.SHA256, false},
- {ECDSAWithSHA1, "ECDSA-SHA1", oidSignatureECDSAWithSHA1, emptyRawValue, ECDSA, crypto.SHA1, false},
- {ECDSAWithSHA256, "ECDSA-SHA256", oidSignatureECDSAWithSHA256, emptyRawValue, ECDSA, crypto.SHA256, false},
- {ECDSAWithSHA384, "ECDSA-SHA384", oidSignatureECDSAWithSHA384, emptyRawValue, ECDSA, crypto.SHA384, false},
- {ECDSAWithSHA512, "ECDSA-SHA512", oidSignatureECDSAWithSHA512, emptyRawValue, ECDSA, crypto.SHA512, false},
- {PureEd25519, "Ed25519", oidSignatureEd25519, emptyRawValue, Ed25519, crypto.Hash(0) /* no pre-hashing */, false},
-}
-
-var emptyRawValue = asn1.RawValue{}
-
-// DER encoded RSA PSS parameters for the
-// SHA256, SHA384, and SHA512 hashes as defined in RFC 3447, Appendix A.2.3.
-// The parameters contain the following values:
-// - hashAlgorithm contains the associated hash identifier with NULL parameters
-// - maskGenAlgorithm always contains the default mgf1SHA1 identifier
-// - saltLength contains the length of the associated hash
-// - trailerField always contains the default trailerFieldBC value
-var (
- pssParametersSHA256 = asn1.RawValue{FullBytes: []byte{48, 52, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 5, 0, 162, 3, 2, 1, 32}}
- pssParametersSHA384 = asn1.RawValue{FullBytes: []byte{48, 52, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 2, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 2, 5, 0, 162, 3, 2, 1, 48}}
- pssParametersSHA512 = asn1.RawValue{FullBytes: []byte{48, 52, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 3, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 3, 5, 0, 162, 3, 2, 1, 64}}
-)
-
-// pssParameters reflects the parameters in an AlgorithmIdentifier that
-// specifies RSA PSS. See RFC 3447, Appendix A.2.3.
-type pssParameters struct {
- // The following three fields are not marked as
- // optional because the default values specify SHA-1,
- // which is no longer suitable for use in signatures.
- Hash pkix.AlgorithmIdentifier `asn1:"explicit,tag:0"`
- MGF pkix.AlgorithmIdentifier `asn1:"explicit,tag:1"`
- SaltLength int `asn1:"explicit,tag:2"`
- TrailerField int `asn1:"optional,explicit,tag:3,default:1"`
-}
-
-func getSignatureAlgorithmFromAI(ai pkix.AlgorithmIdentifier) stdx509.SignatureAlgorithm {
- if ai.Algorithm.Equal(oidSignatureEd25519) {
- // RFC 8410, Section 3
- // > For all of the OIDs, the parameters MUST be absent.
- if len(ai.Parameters.FullBytes) != 0 {
- return stdx509.UnknownSignatureAlgorithm
- }
- }
-
- if !ai.Algorithm.Equal(oidSignatureRSAPSS) {
- for _, details := range signatureAlgorithmDetails {
- if ai.Algorithm.Equal(details.oid) {
- return stdx509.SignatureAlgorithm(details.algo)
- }
- }
- return stdx509.UnknownSignatureAlgorithm
- }
-
- // RSA PSS is special because it encodes important parameters
- // in the Parameters.
-
- var params pssParameters
- if _, err := asn1.Unmarshal(ai.Parameters.FullBytes, &params); err != nil {
- return stdx509.UnknownSignatureAlgorithm
- }
-
- var mgf1HashFunc pkix.AlgorithmIdentifier
- if _, err := asn1.Unmarshal(params.MGF.Parameters.FullBytes, &mgf1HashFunc); err != nil {
- return stdx509.UnknownSignatureAlgorithm
- }
-
- // PSS is greatly overburdened with options. This code forces them into
- // three buckets by requiring that the MGF1 hash function always match the
- // message hash function (as recommended in RFC 3447, Section 8.1), that the
- // salt length matches the hash length, and that the trailer field has the
- // default value.
- if (len(params.Hash.Parameters.FullBytes) != 0 && !bytes.Equal(params.Hash.Parameters.FullBytes, asn1.NullBytes)) ||
- !params.MGF.Algorithm.Equal(oidMGF1) ||
- !mgf1HashFunc.Algorithm.Equal(params.Hash.Algorithm) ||
- (len(mgf1HashFunc.Parameters.FullBytes) != 0 && !bytes.Equal(mgf1HashFunc.Parameters.FullBytes, asn1.NullBytes)) ||
- params.TrailerField != 1 {
- return stdx509.UnknownSignatureAlgorithm
- }
-
- switch {
- case params.Hash.Algorithm.Equal(oidSHA256) && params.SaltLength == 32:
- return stdx509.SHA256WithRSAPSS
- case params.Hash.Algorithm.Equal(oidSHA384) && params.SaltLength == 48:
- return stdx509.SHA384WithRSAPSS
- case params.Hash.Algorithm.Equal(oidSHA512) && params.SaltLength == 64:
- return stdx509.SHA512WithRSAPSS
- }
-
- return stdx509.UnknownSignatureAlgorithm
-}
-
-var (
- // RFC 3279, 2.3 Public Key Algorithms
- //
- // pkcs-1 OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840)
- // rsadsi(113549) pkcs(1) 1 }
- //
- // rsaEncryption OBJECT IDENTIFIER ::== { pkcs1-1 1 }
- //
- // id-dsa OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840)
- // x9-57(10040) x9cm(4) 1 }
- oidPublicKeyRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
- oidPublicKeyDSA = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 1}
- // RFC 5480, 2.1.1 Unrestricted Algorithm Identifier and Parameters
- //
- // id-ecPublicKey OBJECT IDENTIFIER ::= {
- // iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 }
- oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1}
- // RFC 8410, Section 3
- //
- // id-X25519 OBJECT IDENTIFIER ::= { 1 3 101 110 }
- // id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 }
- oidPublicKeyX25519 = asn1.ObjectIdentifier{1, 3, 101, 110}
- oidPublicKeyEd25519 = asn1.ObjectIdentifier{1, 3, 101, 112}
-)
-
-// getPublicKeyAlgorithmFromOID returns the exposed PublicKeyAlgorithm
-// identifier for public key types supported in certificates and CSRs. Marshal
-// and Parse functions may support a different set of public key types.
-func getPublicKeyAlgorithmFromOID(oid asn1.ObjectIdentifier) stdx509.PublicKeyAlgorithm {
- switch {
- case oid.Equal(oidPublicKeyRSA):
- return stdx509.RSA
- case oid.Equal(oidPublicKeyDSA):
- return stdx509.DSA
- case oid.Equal(oidPublicKeyECDSA):
- return stdx509.ECDSA
- case oid.Equal(oidPublicKeyEd25519):
- return stdx509.Ed25519
- }
- return stdx509.UnknownPublicKeyAlgorithm
-}
-
-// RFC 5480, 2.1.1.1. Named Curve
-//
-// secp224r1 OBJECT IDENTIFIER ::= {
-// iso(1) identified-organization(3) certicom(132) curve(0) 33 }
-//
-// secp256r1 OBJECT IDENTIFIER ::= {
-// iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3)
-// prime(1) 7 }
-//
-// secp384r1 OBJECT IDENTIFIER ::= {
-// iso(1) identified-organization(3) certicom(132) curve(0) 34 }
-//
-// secp521r1 OBJECT IDENTIFIER ::= {
-// iso(1) identified-organization(3) certicom(132) curve(0) 35 }
-//
-// NB: secp256r1 is equivalent to prime256v1
-var (
- oidNamedCurveP224 = asn1.ObjectIdentifier{1, 3, 132, 0, 33}
- oidNamedCurveP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7}
- oidNamedCurveP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34}
- oidNamedCurveP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35}
-)
-
-func namedCurveFromOID(oid asn1.ObjectIdentifier) elliptic.Curve {
- switch {
- case oid.Equal(oidNamedCurveP224):
- return elliptic.P224()
- case oid.Equal(oidNamedCurveP256):
- return elliptic.P256()
- case oid.Equal(oidNamedCurveP384):
- return elliptic.P384()
- case oid.Equal(oidNamedCurveP521):
- return elliptic.P521()
- }
- return nil
-}
-
-// KeyUsage represents the set of actions that are valid for a given key. It's
-// a bitmap of the KeyUsage* constants.
-type KeyUsage int
-
-const (
- KeyUsageDigitalSignature KeyUsage = 1 << iota
- KeyUsageContentCommitment
- KeyUsageKeyEncipherment
- KeyUsageDataEncipherment
- KeyUsageKeyAgreement
- KeyUsageCertSign
- KeyUsageCRLSign
- KeyUsageEncipherOnly
- KeyUsageDecipherOnly
-)
-
-// RFC 5280, 4.2.1.12 Extended Key Usage
-//
-// anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 }
-//
-// id-kp OBJECT IDENTIFIER ::= { id-pkix 3 }
-//
-// id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 }
-// id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 }
-// id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 }
-// id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 }
-// id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 }
-// id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 }
-var (
- oidExtKeyUsageAny = asn1.ObjectIdentifier{2, 5, 29, 37, 0}
- oidExtKeyUsageServerAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 1}
- oidExtKeyUsageClientAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 2}
- oidExtKeyUsageCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 3}
- oidExtKeyUsageEmailProtection = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 4}
- oidExtKeyUsageIPSECEndSystem = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 5}
- oidExtKeyUsageIPSECTunnel = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 6}
- oidExtKeyUsageIPSECUser = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 7}
- oidExtKeyUsageTimeStamping = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 8}
- oidExtKeyUsageOCSPSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 9}
- oidExtKeyUsageMicrosoftServerGatedCrypto = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 3}
- oidExtKeyUsageNetscapeServerGatedCrypto = asn1.ObjectIdentifier{2, 16, 840, 1, 113730, 4, 1}
- oidExtKeyUsageMicrosoftCommercialCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 2, 1, 22}
- oidExtKeyUsageMicrosoftKernelCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 61, 1, 1}
-)
-
-// ExtKeyUsage represents an extended set of actions that are valid for a given key.
-// Each of the ExtKeyUsage* constants define a unique action.
-type ExtKeyUsage int
-
-const (
- ExtKeyUsageAny ExtKeyUsage = iota
- ExtKeyUsageServerAuth
- ExtKeyUsageClientAuth
- ExtKeyUsageCodeSigning
- ExtKeyUsageEmailProtection
- ExtKeyUsageIPSECEndSystem
- ExtKeyUsageIPSECTunnel
- ExtKeyUsageIPSECUser
- ExtKeyUsageTimeStamping
- ExtKeyUsageOCSPSigning
- ExtKeyUsageMicrosoftServerGatedCrypto
- ExtKeyUsageNetscapeServerGatedCrypto
- ExtKeyUsageMicrosoftCommercialCodeSigning
- ExtKeyUsageMicrosoftKernelCodeSigning
-)
-
-// extKeyUsageOIDs contains the mapping between an ExtKeyUsage and its OID.
-var extKeyUsageOIDs = []struct {
- extKeyUsage ExtKeyUsage
- oid asn1.ObjectIdentifier
-}{
- {ExtKeyUsageAny, oidExtKeyUsageAny},
- {ExtKeyUsageServerAuth, oidExtKeyUsageServerAuth},
- {ExtKeyUsageClientAuth, oidExtKeyUsageClientAuth},
- {ExtKeyUsageCodeSigning, oidExtKeyUsageCodeSigning},
- {ExtKeyUsageEmailProtection, oidExtKeyUsageEmailProtection},
- {ExtKeyUsageIPSECEndSystem, oidExtKeyUsageIPSECEndSystem},
- {ExtKeyUsageIPSECTunnel, oidExtKeyUsageIPSECTunnel},
- {ExtKeyUsageIPSECUser, oidExtKeyUsageIPSECUser},
- {ExtKeyUsageTimeStamping, oidExtKeyUsageTimeStamping},
- {ExtKeyUsageOCSPSigning, oidExtKeyUsageOCSPSigning},
- {ExtKeyUsageMicrosoftServerGatedCrypto, oidExtKeyUsageMicrosoftServerGatedCrypto},
- {ExtKeyUsageNetscapeServerGatedCrypto, oidExtKeyUsageNetscapeServerGatedCrypto},
- {ExtKeyUsageMicrosoftCommercialCodeSigning, oidExtKeyUsageMicrosoftCommercialCodeSigning},
- {ExtKeyUsageMicrosoftKernelCodeSigning, oidExtKeyUsageMicrosoftKernelCodeSigning},
-}
-
-func extKeyUsageFromOID(oid asn1.ObjectIdentifier) (eku ExtKeyUsage, ok bool) {
- for _, pair := range extKeyUsageOIDs {
- if oid.Equal(pair.oid) {
- return pair.extKeyUsage, true
- }
- }
- return
-}
-
-const (
- nameTypeEmail = 1
- nameTypeDNS = 2
- nameTypeURI = 6
- nameTypeIP = 7
-)
-
-var (
- oidExtensionAuthorityInfoAccess = []int{1, 3, 6, 1, 5, 5, 7, 1, 1}
-)
-
-var (
- oidAuthorityInfoAccessOcsp = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 1}
- oidAuthorityInfoAccessIssuers = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 2}
-)
-
-func isIA5String(s string) error {
- for _, r := range s {
- // Per RFC5280 "IA5String is limited to the set of ASCII characters"
- if r > unicode.MaxASCII {
- return fmt.Errorf("x509: %q cannot be encoded as an IA5String", s)
- }
- }
-
- return nil
-}
diff --git a/vendor/github.com/smallstep/pkcs7/pkcs7.go b/vendor/github.com/smallstep/pkcs7/pkcs7.go
index f6c6dfb..7a7598d 100644
--- a/vendor/github.com/smallstep/pkcs7/pkcs7.go
+++ b/vendor/github.com/smallstep/pkcs7/pkcs7.go
@@ -13,11 +13,8 @@ import (
"errors"
"fmt"
"sort"
- "sync"
_ "crypto/sha1" // for crypto.SHA1
-
- legacyx509 "github.com/smallstep/pkcs7/internal/legacy/x509"
)
// PKCS7 Represents a PKCS7 structure
@@ -216,40 +213,6 @@ func parseEncryptedData(data []byte) (*PKCS7, error) {
}, nil
}
-// SetFallbackLegacyX509CertificateParserEnabled enables parsing certificates
-// embedded in a PKCS7 message using the logic from crypto/x509 from before
-// Go 1.23. Go 1.23 introduced a breaking change in case a certificate contains
-// a critical authority key identifier, which is the correct thing to do based
-// on RFC 5280, but it breaks Windows devices performing the Simple Certificate
-// Enrolment Protocol (SCEP), as the certificates embedded in those requests
-// apparently have authority key identifier extensions marked critical.
-//
-// See https://go-review.googlesource.com/c/go/+/562341 for the change in the
-// Go source.
-//
-// When [SetFallbackLegacyX509CertificateParserEnabled] is called with true, it
-// enables parsing using the legacy crypto/x509 certificate parser. It'll first
-// try to parse the certificates using the regular Go crypto/x509 package, but
-// if it fails on the above case, it'll retry parsing the certificates using a
-// copy of the crypto/x509 package based on Go 1.23, but skips checking the
-// authority key identifier extension being critical or not.
-func SetFallbackLegacyX509CertificateParserEnabled(v bool) {
- legacyX509CertificateParser.Lock()
- legacyX509CertificateParser.enabled = v
- legacyX509CertificateParser.Unlock()
-}
-
-var legacyX509CertificateParser struct {
- sync.RWMutex
- enabled bool
-}
-
-func isLegacyX509ParserEnabled() bool {
- legacyX509CertificateParser.RLock()
- defer legacyX509CertificateParser.RUnlock()
- return legacyX509CertificateParser.enabled
-}
-
func (raw rawCertificates) Parse() ([]*x509.Certificate, error) {
if len(raw.Raw) == 0 {
return nil, nil
@@ -260,14 +223,7 @@ func (raw rawCertificates) Parse() ([]*x509.Certificate, error) {
return nil, err
}
- certificates, err := x509.ParseCertificates(val.Bytes)
- if err != nil && err.Error() == "x509: authority key identifier incorrectly marked critical" {
- if isLegacyX509ParserEnabled() {
- certificates, err = legacyx509.ParseCertificates(val.Bytes)
- }
- }
-
- return certificates, err
+ return x509.ParseCertificates(val.Bytes)
}
func isCertMatchForIssuerAndSerial(cert *x509.Certificate, ias issuerAndSerial) bool {
diff --git a/vendor/github.com/smallstep/pkcs7/verify.go b/vendor/github.com/smallstep/pkcs7/verify.go
index 7525f91..2c6f32c 100644
--- a/vendor/github.com/smallstep/pkcs7/verify.go
+++ b/vendor/github.com/smallstep/pkcs7/verify.go
@@ -54,21 +54,6 @@ func (p7 *PKCS7) VerifyWithChainAtTime(truststore *x509.CertPool, currentTime ti
return nil
}
-// SigningTimeNotValidError is returned when the signing time attribute
-// falls outside of the signer certificate validity.
-type SigningTimeNotValidError struct {
- SigningTime time.Time
- NotBefore time.Time // NotBefore of signer
- NotAfter time.Time // NotAfter of signer
-}
-
-func (e *SigningTimeNotValidError) Error() string {
- return fmt.Sprintf("pkcs7: signing time %q is outside of certificate validity %q to %q",
- e.SigningTime.Format(time.RFC3339),
- e.NotBefore.Format(time.RFC3339),
- e.NotAfter.Format(time.RFC3339))
-}
-
func verifySignatureAtTime(p7 *PKCS7, signer signerInfo, truststore *x509.CertPool, currentTime time.Time) (err error) {
signedData := p7.Content
ee := getCertFromCertsByIssuerAndSerial(p7.Certificates, signer.IssuerAndSerialNumber)
@@ -106,11 +91,10 @@ func verifySignatureAtTime(p7 *PKCS7, signer signerInfo, truststore *x509.CertPo
if err == nil {
// signing time found, performing validity check
if signingTime.After(ee.NotAfter) || signingTime.Before(ee.NotBefore) {
- return &SigningTimeNotValidError{
- SigningTime: signingTime,
- NotBefore: ee.NotBefore,
- NotAfter: ee.NotAfter,
- }
+ return fmt.Errorf("pkcs7: signing time %q is outside of certificate validity %q to %q",
+ signingTime.Format(time.RFC3339),
+ ee.NotBefore.Format(time.RFC3339),
+ ee.NotAfter.Format(time.RFC3339))
}
}
}
@@ -162,11 +146,10 @@ func verifySignature(p7 *PKCS7, signer signerInfo, truststore *x509.CertPool) (e
if err == nil {
// signing time found, performing validity check
if signingTime.After(ee.NotAfter) || signingTime.Before(ee.NotBefore) {
- return &SigningTimeNotValidError{
- SigningTime: signingTime,
- NotBefore: ee.NotBefore,
- NotAfter: ee.NotAfter,
- }
+ return fmt.Errorf("pkcs7: signing time %q is outside of certificate validity %q to %q",
+ signingTime.Format(time.RFC3339),
+ ee.NotBefore.Format(time.RFC3339),
+ ee.NotAfter.Format(time.RFC3339))
}
}
}
diff --git a/vendor/github.com/smallstep/pkcs7/verify_test_dsa.go b/vendor/github.com/smallstep/pkcs7/verify_test_dsa.go
new file mode 100644
index 0000000..1eb05bc
--- /dev/null
+++ b/vendor/github.com/smallstep/pkcs7/verify_test_dsa.go
@@ -0,0 +1,182 @@
+// +build go1.11 go1.12 go1.13 go1.14 go1.15
+
+package pkcs7
+
+import (
+ "crypto/x509"
+ "encoding/pem"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "testing"
+)
+
+func TestVerifyEC2(t *testing.T) {
+ fixture := UnmarshalDSATestFixture(EC2IdentityDocumentFixture)
+ p7, err := Parse(fixture.Input)
+ if err != nil {
+ t.Errorf("Parse encountered unexpected error: %v", err)
+ }
+ p7.Certificates = []*x509.Certificate{fixture.Certificate}
+ if err := p7.Verify(); err != nil {
+ t.Errorf("Verify failed with error: %v", err)
+ }
+}
+
+var EC2IdentityDocumentFixture = `
+-----BEGIN PKCS7-----
+MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCA
+JIAEggGmewogICJwcml2YXRlSXAiIDogIjE3Mi4zMC4wLjI1MiIsCiAgImRldnBh
+eVByb2R1Y3RDb2RlcyIgOiBudWxsLAogICJhdmFpbGFiaWxpdHlab25lIiA6ICJ1
+cy1lYXN0LTFhIiwKICAidmVyc2lvbiIgOiAiMjAxMC0wOC0zMSIsCiAgImluc3Rh
+bmNlSWQiIDogImktZjc5ZmU1NmMiLAogICJiaWxsaW5nUHJvZHVjdHMiIDogbnVs
+bCwKICAiaW5zdGFuY2VUeXBlIiA6ICJ0Mi5taWNybyIsCiAgImFjY291bnRJZCIg
+OiAiMTIxNjU5MDE0MzM0IiwKICAiaW1hZ2VJZCIgOiAiYW1pLWZjZTNjNjk2IiwK
+ICAicGVuZGluZ1RpbWUiIDogIjIwMTYtMDQtMDhUMDM6MDE6MzhaIiwKICAiYXJj
+aGl0ZWN0dXJlIiA6ICJ4ODZfNjQiLAogICJrZXJuZWxJZCIgOiBudWxsLAogICJy
+YW1kaXNrSWQiIDogbnVsbCwKICAicmVnaW9uIiA6ICJ1cy1lYXN0LTEiCn0AAAAA
+AAAxggEYMIIBFAIBATBpMFwxCzAJBgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5n
+dG9uIFN0YXRlMRAwDgYDVQQHEwdTZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2Vi
+IFNlcnZpY2VzIExMQwIJAJa6SNnlXhpnMAkGBSsOAwIaBQCgXTAYBgkqhkiG9w0B
+CQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xNjA0MDgwMzAxNDRaMCMG
+CSqGSIb3DQEJBDEWBBTuUc28eBXmImAautC+wOjqcFCBVjAJBgcqhkjOOAQDBC8w
+LQIVAKA54NxGHWWCz5InboDmY/GHs33nAhQ6O/ZI86NwjA9Vz3RNMUJrUPU5tAAA
+AAAAAA==
+-----END PKCS7-----
+-----BEGIN CERTIFICATE-----
+MIIC7TCCAq0CCQCWukjZ5V4aZzAJBgcqhkjOOAQDMFwxCzAJBgNVBAYTAlVTMRkw
+FwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdTZWF0dGxlMSAwHgYD
+VQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQzAeFw0xMjAxMDUxMjU2MTJaFw0z
+ODAxMDUxMjU2MTJaMFwxCzAJBgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9u
+IFN0YXRlMRAwDgYDVQQHEwdTZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNl
+cnZpY2VzIExMQzCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQCjkvcS2bb1VQ4yt/5e
+ih5OO6kK/n1Lzllr7D8ZwtQP8fOEpp5E2ng+D6Ud1Z1gYipr58Kj3nssSNpI6bX3
+VyIQzK7wLclnd/YozqNNmgIyZecN7EglK9ITHJLP+x8FtUpt3QbyYXJdmVMegN6P
+hviYt5JH/nYl4hh3Pa1HJdskgQIVALVJ3ER11+Ko4tP6nwvHwh6+ERYRAoGBAI1j
+k+tkqMVHuAFcvAGKocTgsjJem6/5qomzJuKDmbJNu9Qxw3rAotXau8Qe+MBcJl/U
+hhy1KHVpCGl9fueQ2s6IL0CaO/buycU1CiYQk40KNHCcHfNiZbdlx1E9rpUp7bnF
+lRa2v1ntMX3caRVDdbtPEWmdxSCYsYFDk4mZrOLBA4GEAAKBgEbmeve5f8LIE/Gf
+MNmP9CM5eovQOGx5ho8WqD+aTebs+k2tn92BBPqeZqpWRa5P/+jrdKml1qx4llHW
+MXrs3IgIb6+hUIB+S8dz8/mmO0bpr76RoZVCXYab2CZedFut7qc3WUH9+EUAH5mw
+vSeDCOUMYQR7R9LINYwouHIziqQYMAkGByqGSM44BAMDLwAwLAIUWXBlk40xTwSw
+7HX32MxXYruse9ACFBNGmdX2ZBrVNGrN9N2f6ROk0k9K
+-----END CERTIFICATE-----`
+
+func TestDSASignWithOpenSSLAndVerify(t *testing.T) {
+ content := []byte(`
+A ship in port is safe,
+but that's not what ships are built for.
+-- Grace Hopper`)
+ // write the content to a temp file
+ tmpContentFile, err := ioutil.TempFile("", "TestDSASignWithOpenSSLAndVerify_content")
+ if err != nil {
+ t.Fatal(err)
+ }
+ ioutil.WriteFile(tmpContentFile.Name(), content, 0755)
+
+ // write the signer cert to a temp file
+ tmpSignerCertFile, err := ioutil.TempFile("", "TestDSASignWithOpenSSLAndVerify_signer")
+ if err != nil {
+ t.Fatal(err)
+ }
+ ioutil.WriteFile(tmpSignerCertFile.Name(), dsaPublicCert, 0755)
+
+ // write the signer key to a temp file
+ tmpSignerKeyFile, err := ioutil.TempFile("", "TestDSASignWithOpenSSLAndVerify_key")
+ if err != nil {
+ t.Fatal(err)
+ }
+ ioutil.WriteFile(tmpSignerKeyFile.Name(), dsaPrivateKey, 0755)
+
+ tmpSignedFile, err := ioutil.TempFile("", "TestDSASignWithOpenSSLAndVerify_signature")
+ if err != nil {
+ t.Fatal(err)
+ }
+ // call openssl to sign the content
+ opensslCMD := exec.Command("openssl", "smime", "-sign", "-nodetach", "-md", "sha1",
+ "-in", tmpContentFile.Name(), "-out", tmpSignedFile.Name(),
+ "-signer", tmpSignerCertFile.Name(), "-inkey", tmpSignerKeyFile.Name(),
+ "-certfile", tmpSignerCertFile.Name(), "-outform", "PEM")
+ out, err := opensslCMD.CombinedOutput()
+ if err != nil {
+ t.Fatalf("openssl command failed with %s: %s", err, out)
+ }
+
+ // verify the signed content
+ pemSignature, err := ioutil.ReadFile(tmpSignedFile.Name())
+ if err != nil {
+ t.Fatal(err)
+ }
+ fmt.Printf("%s\n", pemSignature)
+ derBlock, _ := pem.Decode(pemSignature)
+ if derBlock == nil {
+ t.Fatalf("failed to read DER block from signature PEM %s", tmpSignedFile.Name())
+ }
+ p7, err := Parse(derBlock.Bytes)
+ if err != nil {
+ t.Fatalf("Parse encountered unexpected error: %v", err)
+ }
+ if err := p7.Verify(); err != nil {
+ t.Fatalf("Verify failed with error: %v", err)
+ }
+ os.Remove(tmpSignerCertFile.Name()) // clean up
+ os.Remove(tmpSignerKeyFile.Name()) // clean up
+ os.Remove(tmpContentFile.Name()) // clean up
+}
+
+var dsaPrivateKey = []byte(`-----BEGIN PRIVATE KEY-----
+MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdS
+PO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVCl
+pJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith
+1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7L
+vKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3
+zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImo
+g9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoEFgIUfW4aPdQBn9gJZp2KuNpzgHzvfsE=
+-----END PRIVATE KEY-----`)
+
+var dsaPublicCert = []byte(`-----BEGIN CERTIFICATE-----
+MIIDOjCCAvWgAwIBAgIEPCY/UDANBglghkgBZQMEAwIFADBsMRAwDgYDVQQGEwdV
+bmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYD
+VQQKEwdVbmtub3duMRAwDgYDVQQLEwdVbmtub3duMRAwDgYDVQQDEwdVbmtub3du
+MB4XDTE4MTAyMjEzNDMwN1oXDTQ2MDMwOTEzNDMwN1owbDEQMA4GA1UEBhMHVW5r
+bm93bjEQMA4GA1UECBMHVW5rbm93bjEQMA4GA1UEBxMHVW5rbm93bjEQMA4GA1UE
+ChMHVW5rbm93bjEQMA4GA1UECxMHVW5rbm93bjEQMA4GA1UEAxMHVW5rbm93bjCC
+AbgwggEsBgcqhkjOOAQBMIIBHwKBgQD9f1OBHXUSKVLfSpwu7OTn9hG3UjzvRADD
+Hj+AtlEmaUVdQCJR+1k9jVj6v8X1ujD2y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gE
+exAiwk+7qdf+t8Yb+DtX58aophUPBPuD9tPFHsMCNVQTWhaRMvZ1864rYdcq7/Ii
+Axmd0UgBxwIVAJdgUI8VIwvMspK5gqLrhAvwWBz1AoGBAPfhoIXWmz3ey7yrXDa4
+V7l5lK+7+jrqgvlXTAs9B4JnUVlXjrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozI
+puE8FnqLVHyNKOCjrh4rs6Z1kW6jfwv6ITVi8ftiegEkO8yk8b6oUZCJqIPf4Vrl
+nwaSi2ZegHtVJWQBTDv+z0kqA4GFAAKBgQDCriMPbEVBoRK4SOUeFwg7+VRf4TTp
+rcOQC9IVVoCjXzuWEGrp3ZI7YWJSpFnSch4lk29RH8O0HpI/NOzKnOBtnKr782pt
+1k/bJVMH9EaLd6MKnAVjrCDMYBB0MhebZ8QHY2elZZCWoqDYAcIDOsEx+m4NLErT
+ypPnjS5M0jm1PKMhMB8wHQYDVR0OBBYEFC0Yt5XdM0Kc95IX8NQ8XRssGPx7MA0G
+CWCGSAFlAwQDAgUAAzAAMC0CFQCIgQtrZZ9hdZG1ROhR5hc8nYEmbgIUAIlgC688
+qzy/7yePTlhlpj+ahMM=
+-----END CERTIFICATE-----`)
+
+type DSATestFixture struct {
+ Input []byte
+ Certificate *x509.Certificate
+}
+
+func UnmarshalDSATestFixture(testPEMBlock string) DSATestFixture {
+ var result DSATestFixture
+ var derBlock *pem.Block
+ var pemBlock = []byte(testPEMBlock)
+ for {
+ derBlock, pemBlock = pem.Decode(pemBlock)
+ if derBlock == nil {
+ break
+ }
+ switch derBlock.Type {
+ case "PKCS7":
+ result.Input = derBlock.Bytes
+ case "CERTIFICATE":
+ result.Certificate, _ = x509.ParseCertificate(derBlock.Bytes)
+ }
+ }
+
+ return result
+}
diff --git a/vendor/github.com/smallstep/scep/scep.go b/vendor/github.com/smallstep/scep/scep.go
index 8004af2..d922866 100644
--- a/vendor/github.com/smallstep/scep/scep.go
+++ b/vendor/github.com/smallstep/scep/scep.go
@@ -14,6 +14,7 @@ import (
"errors"
"fmt"
+ "github.com/go-kit/kit/log/level"
"github.com/smallstep/pkcs7"
"github.com/smallstep/scep/cryptoutil"
@@ -26,6 +27,12 @@ var (
errUnknownMessageType = errors.New("scep: unknown messageType")
)
+// prepare the go-kit leveled logging configuration
+var (
+ levelKey = level.Key()
+ levelDebug = level.DebugValue()
+)
+
// The MessageType attribute specifies the type of operation performed
// by the transaction. This attribute MUST be included in all PKI
// messages.
@@ -142,7 +149,7 @@ func WithLogger(logger Logger) Option {
}
// WithCACerts adds option CA certificates to the SCEP operations.
-// Note: This changes the verification behavior of PKCS#7 messages. If this
+// Note: This changes the verification behavior of PKCS #7 messages. If this
// option is specified, only caCerts will be used as expected signers.
func WithCACerts(caCerts []*x509.Certificate) Option {
return func(c *config) {
@@ -154,7 +161,7 @@ func WithCACerts(caCerts []*x509.Certificate) Option {
// operations.
// This option is effective when used with NewCSRRequest function. In
// this case, only certificates selected with the certsSelector will be used
-// as the PKCS#7 message recipients.
+// as the PKCS #7 message recipients.
func WithCertsSelector(selector CertsSelector) Option {
return func(c *config) {
c.certsSelector = selector
@@ -191,7 +198,7 @@ type PKIMessage struct {
Recipients []*x509.Certificate
// Signer info
- SignerKey crypto.PrivateKey
+ SignerKey *rsa.PrivateKey
SignerCert *x509.Certificate
logger Logger
@@ -240,7 +247,7 @@ func ParsePKIMessage(data []byte, opts ...Option) (*PKIMessage, error) {
// signatures have an alternate means of obtaining necessary certificates.
// In SCEP case, an alternate means is to use GetCaCert request.
// Note: The https://github.com/jscep/jscep implementation logs a warning if
- // no certificates were found for signers in the PKCS#7 received from the
+ // no certificates were found for signers in the PKCS #7 received from the
// server, but the certificates obtained from GetCaCert request are still
// used for decoding the message.
p7.Certificates = conf.caCerts
@@ -269,6 +276,7 @@ func ParsePKIMessage(data []byte, opts ...Option) (*PKIMessage, error) {
}
msg.logger.Log(
+ levelKey, levelDebug,
"msg", "parsed scep pkiMessage",
"scep_message_type", msgType,
"transaction_id", tID,
@@ -335,22 +343,8 @@ func (msg *PKIMessage) parseMessageType() error {
}
}
-// DecryptPKIEnvelope decrypts the PKCS#7 envelopedData inside the SCEP PKIMessage
-func (msg *PKIMessage) DecryptPKIEnvelope(cert *x509.Certificate, key crypto.PrivateKey) error {
- if cert == nil {
- return errors.New("scep: cert must not be nil")
- }
- if key == nil {
- return errors.New("scep: key must not be nil")
- }
- decrypter, ok := key.(crypto.Decrypter)
- if !ok {
- return errors.New("scep: private key does not implement crypto.Decrypter")
- }
- if _, ok := decrypter.Public().(*rsa.PublicKey); !ok {
- return fmt.Errorf("scep: key.Public() returned type %T; expected *rsa.PublicKey", decrypter.Public())
- }
-
+// DecryptPKIEnvelope decrypts the pkcs envelopedData inside the SCEP PKIMessage
+func (msg *PKIMessage) DecryptPKIEnvelope(cert *x509.Certificate, key *rsa.PrivateKey) error {
p7, err := pkcs7.Parse(msg.p7.Content)
if err != nil {
return err
@@ -361,6 +355,7 @@ func (msg *PKIMessage) DecryptPKIEnvelope(cert *x509.Certificate, key crypto.Pri
}
logKeyVals := []interface{}{
+ levelKey, levelDebug,
"msg", "decrypt pkiEnvelope",
}
defer func() { msg.logger.Log(logKeyVals...) }()
@@ -398,8 +393,7 @@ func (msg *PKIMessage) DecryptPKIEnvelope(cert *x509.Certificate, key crypto.Pri
}
}
-// Fail returns a new PKIMessage with CertRep data indicating a failure
-func (msg *PKIMessage) Fail(crtAuth *x509.Certificate, keyAuth crypto.PrivateKey, info FailInfo) (*PKIMessage, error) {
+func (msg *PKIMessage) Fail(crtAuth *x509.Certificate, keyAuth *rsa.PrivateKey, info FailInfo) (*PKIMessage, error) {
config := pkcs7.SignerInfoConfig{
ExtraSignedAttributes: []pkcs7.Attribute{
{
@@ -462,9 +456,9 @@ func (msg *PKIMessage) Fail(crtAuth *x509.Certificate, keyAuth crypto.PrivateKey
}
// Success returns a new PKIMessage with CertRep data using an already-issued certificate
-func (msg *PKIMessage) Success(crtAuth *x509.Certificate, keyAuth crypto.PrivateKey, crt *x509.Certificate) (*PKIMessage, error) {
+func (msg *PKIMessage) Success(crtAuth *x509.Certificate, keyAuth *rsa.PrivateKey, crt *x509.Certificate) (*PKIMessage, error) {
// check if CSRReqMessage has already been decrypted
- if msg.CSRReqMessage.CSR == nil { // TODO(hslatman): remove this; just require decryption before, so that we can make keyAuth a crypto.Signer
+ if msg.CSRReqMessage.CSR == nil {
if err := msg.DecryptPKIEnvelope(crtAuth, keyAuth); err != nil {
return nil, err
}
@@ -544,7 +538,7 @@ func (msg *PKIMessage) Success(crtAuth *x509.Certificate, keyAuth crypto.Private
return crepMsg, nil
}
-// DegenerateCertificates creates degenerate certificates PKCS#7 type
+// DegenerateCertificates creates degenerate certificates pkcs#7 type
func DegenerateCertificates(certs []*x509.Certificate) ([]byte, error) {
var buf bytes.Buffer
for _, cert := range certs {
@@ -557,7 +551,7 @@ func DegenerateCertificates(certs []*x509.Certificate) ([]byte, error) {
return degenerate, nil
}
-// CACerts extract CA Certificate or chain from PKCS#7 degenerate signed data
+// CACerts extract CA Certificate or chain from pkcs7 degenerate signed data
func CACerts(data []byte) ([]*x509.Certificate, error) {
p7, err := pkcs7.Parse(data)
if err != nil {
@@ -604,6 +598,7 @@ func NewCSRRequest(csr *x509.CertificateRequest, tmpl *PKIMessage, opts ...Optio
}
conf.logger.Log(
+ levelKey, levelDebug,
"msg", "creating SCEP CSR request",
"transaction_id", tID,
"signer_cn", tmpl.SignerCert.Subject.CommonName,
diff --git a/vendor/github.com/smallstep/scep/x509util/x509util.go b/vendor/github.com/smallstep/scep/x509util/x509util.go
index 53f9517..0e65409 100644
--- a/vendor/github.com/smallstep/scep/x509util/x509util.go
+++ b/vendor/github.com/smallstep/scep/x509util/x509util.go
@@ -55,7 +55,7 @@ type CertificateRequest struct {
// challengePassword attribute.
//
// See https://github.com/golang/go/issues/15995
-func CreateCertificateRequest(rand io.Reader, template *CertificateRequest, priv crypto.PrivateKey) (csr []byte, err error) {
+func CreateCertificateRequest(rand io.Reader, template *CertificateRequest, priv interface{}) (csr []byte, err error) {
if template.ChallengePassword == "" {
// if no challenge password, return a stdlib CSR.
return x509.CreateCertificateRequest(rand, &template.CertificateRequest, priv)