From c60641701bb25577ed56e986aee73247cef23bb8 Mon Sep 17 00:00:00 2001 From: Mariano Cano Date: Wed, 20 Nov 2019 17:01:31 -0800 Subject: [PATCH] Add version endpoint. --- api/api.go | 46 ++++++++++++++++++++++++++++++++++++++++++ authority/authority.go | 3 +-- cmd/step-ca/main.go | 2 ++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/api/api.go b/api/api.go index 334def24..1fb0230a 100644 --- a/api/api.go +++ b/api/api.go @@ -42,6 +42,7 @@ type Authority interface { GetEncryptedKey(kid string) (string, error) GetRoots() (federation []*x509.Certificate, err error) GetFederation() ([]*x509.Certificate, error) + Version() authority.Version } // TimeDuration is an alias of provisioner.TimeDuration @@ -71,6 +72,13 @@ func NewCertificate(cr *x509.Certificate) Certificate { } } +// reset sets the inner x509.CertificateRequest to nil +func (c *Certificate) reset() { + if c != nil { + c.Certificate = nil + } +} + // MarshalJSON implements the json.Marshaler interface. The certificate is // quoted string using the PEM encoding. func (c Certificate) MarshalJSON() ([]byte, error) { @@ -91,6 +99,13 @@ func (c *Certificate) UnmarshalJSON(data []byte) error { if err := json.Unmarshal(data, &s); err != nil { return errors.Wrap(err, "error decoding certificate") } + + // Make sure the inner x509.Certificate is nil + if s == "null" || s == "" { + c.reset() + return nil + } + block, _ := pem.Decode([]byte(s)) if block == nil { return errors.New("error decoding certificate") @@ -117,6 +132,13 @@ func NewCertificateRequest(cr *x509.CertificateRequest) CertificateRequest { } } +// reset sets the inner x509.CertificateRequest to nil +func (c *CertificateRequest) reset() { + if c != nil { + c.CertificateRequest = nil + } +} + // MarshalJSON implements the json.Marshaler interface. The certificate request // is a quoted string using the PEM encoding. func (c CertificateRequest) MarshalJSON() ([]byte, error) { @@ -137,6 +159,13 @@ func (c *CertificateRequest) UnmarshalJSON(data []byte) error { if err := json.Unmarshal(data, &s); err != nil { return errors.Wrap(err, "error decoding csr") } + + // Make sure the inner x509.CertificateRequest is nil + if s == "null" || s == "" { + c.reset() + return nil + } + block, _ := pem.Decode([]byte(s)) if block == nil { return errors.New("error decoding csr") @@ -162,6 +191,13 @@ type RouterHandler interface { Route(r Router) } +// VersionResponse is the response object that returns the version of the +// server. +type VersionResponse struct { + Version string `json:"version"` + RequireClientAuthentication bool `json:"requireClientAuthentication,omitempty"` +} + // HealthResponse is the response object that returns the health of the server. type HealthResponse struct { Status string `json:"status"` @@ -241,6 +277,7 @@ func New(authority Authority) RouterHandler { } func (h *caHandler) Route(r Router) { + r.MethodFunc("GET", "/version", h.Version) r.MethodFunc("GET", "/health", h.Health) r.MethodFunc("GET", "/root/{sha}", h.Root) r.MethodFunc("POST", "/sign", h.Sign) @@ -268,6 +305,15 @@ func (h *caHandler) Route(r Router) { r.MethodFunc("POST", "/sign-ssh", h.SSHSign) } +// Version is an HTTP handler that returns the version of the server. +func (h *caHandler) Version(w http.ResponseWriter, r *http.Request) { + v := h.Authority.Version() + JSON(w, VersionResponse{ + Version: v.Version, + RequireClientAuthentication: v.RequireClientAuthentication, + }) +} + // Health is an HTTP handler that returns the status of the server. func (h *caHandler) Health(w http.ResponseWriter, r *http.Request) { JSON(w, HealthResponse{Status: "ok"}) diff --git a/authority/authority.go b/authority/authority.go index 44fe3fc7..9faf3348 100644 --- a/authority/authority.go +++ b/authority/authority.go @@ -8,11 +8,10 @@ import ( "sync" "time" - "github.com/smallstep/certificates/templates" - "github.com/pkg/errors" "github.com/smallstep/certificates/authority/provisioner" "github.com/smallstep/certificates/db" + "github.com/smallstep/certificates/templates" "github.com/smallstep/cli/crypto/pemutil" "github.com/smallstep/cli/crypto/x509util" "golang.org/x/crypto/ssh" diff --git a/cmd/step-ca/main.go b/cmd/step-ca/main.go index 3e47d52f..d3ed089c 100644 --- a/cmd/step-ca/main.go +++ b/cmd/step-ca/main.go @@ -13,6 +13,7 @@ import ( "strconv" "time" + "github.com/smallstep/certificates/authority" "github.com/smallstep/certificates/commands" "github.com/smallstep/cli/command" "github.com/smallstep/cli/command/version" @@ -29,6 +30,7 @@ var ( func init() { config.Set("Smallstep CA", Version, BuildTime) + authority.GlobalVersion.Version = Version rand.Seed(time.Now().UnixNano()) }