Add certificate information to logs.

Fixes smallstep/ca-component#147
This commit is contained in:
Mariano Cano 2019-02-19 19:45:52 -08:00
parent 37d7231ee0
commit b974957868
2 changed files with 62 additions and 2 deletions

View file

@ -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)
}

View file

@ -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 {