1// Package certinfo implements the HTTP handler for the certinfo command. 2package certinfo 3 4import ( 5 "errors" 6 "net/http" 7 8 "github.com/cloudflare/cfssl/api" 9 "github.com/cloudflare/cfssl/certdb" 10 "github.com/cloudflare/cfssl/certinfo" 11 "github.com/cloudflare/cfssl/log" 12) 13 14// Handler accepts requests for either remote or uploaded 15// certificates to be bundled, and returns a certificate bundle (or 16// error). 17type Handler struct { 18 dbAccessor certdb.Accessor 19} 20 21// NewHandler creates a new bundler that uses the root bundle and 22// intermediate bundle in the trust chain. 23func NewHandler() http.Handler { 24 return api.HTTPHandler{Handler: new(Handler), Methods: []string{"POST"}} 25} 26 27// NewAccessorHandler creates a new bundler with database access via the 28// certdb.Accessor interface. If this handler is constructed it will be possible 29// to lookup certificates issued earlier by the CA. 30func NewAccessorHandler(dbAccessor certdb.Accessor) http.Handler { 31 return api.HTTPHandler{ 32 Handler: &Handler{ 33 dbAccessor: dbAccessor, 34 }, 35 Methods: []string{"POST"}, 36 } 37} 38 39// Handle implements an http.Handler interface for the bundle handler. 40func (h *Handler) Handle(w http.ResponseWriter, r *http.Request) (err error) { 41 blob, matched, err := api.ProcessRequestFirstMatchOf(r, 42 [][]string{ 43 {"certificate"}, 44 {"domain"}, 45 {"serial", "authority_key_id"}, 46 }) 47 if err != nil { 48 log.Warningf("invalid request: %v", err) 49 return err 50 } 51 52 var cert *certinfo.Certificate 53 switch matched[0] { 54 case "domain": 55 if cert, err = certinfo.ParseCertificateDomain(blob["domain"]); err != nil { 56 log.Warningf("couldn't parse remote certificate: %v", err) 57 return err 58 } 59 case "certificate": 60 if cert, err = certinfo.ParseCertificatePEM([]byte(blob["certificate"])); err != nil { 61 log.Warningf("bad PEM certifcate: %v", err) 62 return err 63 } 64 case "serial", "authority_key_id": 65 if h.dbAccessor == nil { 66 log.Warning("could not find certificates with db access") 67 68 return errors.New("cannot lookup certificate from serial without db access") 69 } 70 71 if cert, err = certinfo.ParseSerialNumber(blob["serial"], blob["authority_key_id"], h.dbAccessor); err != nil { 72 log.Warningf("couldn't find certificate: %v", err) 73 74 return err 75 } 76 } 77 78 return api.SendResponse(w, cert) 79} 80