From b97495786805453dd2e6692f41ed7262072294d7 Mon Sep 17 00:00:00 2001 From: Mariano Cano Date: Tue, 19 Feb 2019 19:45:52 -0800 Subject: [PATCH] Add certificate information to logs. Fixes smallstep/ca-component#147 --- api/api.go | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ api/api_test.go | 5 +++-- 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/api/api.go b/api/api.go index 4bdf1b09..edd21237 100644 --- a/api/api.go +++ b/api/api.go @@ -1,10 +1,15 @@ package api import ( + "crypto/ecdsa" + "crypto/rsa" "crypto/tls" "crypto/x509" + "encoding/asn1" + "encoding/base64" "encoding/json" "encoding/pem" + "fmt" "net/http" "strconv" "strings" @@ -13,6 +18,7 @@ import ( "github.com/go-chi/chi" "github.com/pkg/errors" "github.com/smallstep/certificates/authority" + "github.com/smallstep/certificates/logging" "github.com/smallstep/cli/crypto/tlsutil" ) @@ -275,6 +281,7 @@ func (h *caHandler) Sign(w http.ResponseWriter, r *http.Request) { } w.WriteHeader(http.StatusCreated) + logCertificate(w, cert, body.OTT) JSON(w, &SignResponse{ ServerPEM: Certificate{cert}, CaPEM: Certificate{root}, @@ -297,6 +304,7 @@ func (h *caHandler) Renew(w http.ResponseWriter, r *http.Request) { } w.WriteHeader(http.StatusCreated) + logCertificate(w, cert, "") JSON(w, &SignResponse{ ServerPEM: Certificate{cert}, CaPEM: Certificate{root}, @@ -372,6 +380,43 @@ func (h *caHandler) Federation(w http.ResponseWriter, r *http.Request) { }) } +var oidStepProvisioner = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 37476, 9000, 64, 1} + +type stepProvisioner struct { + Type int + Name []byte + CredentialID []byte +} + +func logCertificate(w http.ResponseWriter, cert *x509.Certificate, token string) { + if rl, ok := w.(logging.ResponseLogger); ok { + m := map[string]interface{}{ + "serial": cert.SerialNumber, + "subject": cert.Subject.CommonName, + "issuer": cert.Issuer.CommonName, + "valid-from": cert.NotBefore.Format(time.RFC3339), + "valid-to": cert.NotAfter.Format(time.RFC3339), + "public-key": fmtPublicKey(cert), + "certificate": base64.StdEncoding.EncodeToString(cert.Raw), + } + if len(token) > 0 { + m["ott"] = token + } + for _, ext := range cert.Extensions { + if ext.Id.Equal(oidStepProvisioner) { + val := &stepProvisioner{} + rest, err := asn1.Unmarshal(ext.Value, val) + if err != nil || len(rest) > 0 { + break + } + m["provisioner"] = fmt.Sprintf("%s (%s)", val.Name, val.CredentialID) + break + } + } + rl.WithFields(m) + } +} + func parseCursor(r *http.Request) (cursor string, limit int, err error) { q := r.URL.Query() cursor = q.Get("cursor") @@ -383,3 +428,17 @@ func parseCursor(r *http.Request) (cursor string, limit int, err error) { } return } + +// TODO: add support for Ed25519 once it's supported +func fmtPublicKey(cert *x509.Certificate) string { + var params string + switch pk := cert.PublicKey.(type) { + case *ecdsa.PublicKey: + params = pk.Curve.Params().Name + case *rsa.PublicKey: + params = strconv.Itoa(pk.Size()) + default: + params = "unknown" + } + return fmt.Sprintf("%s %s", cert.PublicKeyAlgorithm, params) +} diff --git a/api/api_test.go b/api/api_test.go index 988b46dd..b2db1796 100644 --- a/api/api_test.go +++ b/api/api_test.go @@ -18,6 +18,7 @@ import ( "github.com/go-chi/chi" "github.com/smallstep/certificates/authority" + "github.com/smallstep/certificates/logging" "github.com/smallstep/cli/crypto/tlsutil" "github.com/smallstep/cli/jose" ) @@ -598,7 +599,7 @@ func Test_caHandler_Sign(t *testing.T) { }).(*caHandler) req := httptest.NewRequest("POST", "http://example.com/sign", strings.NewReader(tt.input)) w := httptest.NewRecorder() - h.Sign(w, req) + h.Sign(logging.NewResponseLogger(w), req) res := w.Result() if res.StatusCode != tt.statusCode { @@ -650,7 +651,7 @@ func Test_caHandler_Renew(t *testing.T) { req := httptest.NewRequest("POST", "http://example.com/renew", nil) req.TLS = tt.tls w := httptest.NewRecorder() - h.Renew(w, req) + h.Renew(logging.NewResponseLogger(w), req) res := w.Result() if res.StatusCode != tt.statusCode {