92 lines
2.3 KiB
Go
92 lines
2.3 KiB
Go
// Package bundle implements the HTTP handler for the bundle command.
|
|
package bundle
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/cloudflare/cfssl/api"
|
|
"github.com/cloudflare/cfssl/bundler"
|
|
"github.com/cloudflare/cfssl/errors"
|
|
"github.com/cloudflare/cfssl/log"
|
|
)
|
|
|
|
// Handler accepts requests for either remote or uploaded
|
|
// certificates to be bundled, and returns a certificate bundle (or
|
|
// error).
|
|
type Handler struct {
|
|
bundler *bundler.Bundler
|
|
}
|
|
|
|
// NewHandler creates a new bundler that uses the root bundle and
|
|
// intermediate bundle in the trust chain.
|
|
func NewHandler(caBundleFile, intBundleFile string) (http.Handler, error) {
|
|
var err error
|
|
|
|
b := new(Handler)
|
|
if b.bundler, err = bundler.NewBundler(caBundleFile, intBundleFile); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
log.Info("bundler API ready")
|
|
return api.HTTPHandler{Handler: b, Methods: []string{"POST"}}, nil
|
|
}
|
|
|
|
// Handle implements an http.Handler interface for the bundle handler.
|
|
func (h *Handler) Handle(w http.ResponseWriter, r *http.Request) error {
|
|
blob, matched, err := api.ProcessRequestFirstMatchOf(r,
|
|
[][]string{
|
|
{"certificate"},
|
|
{"domain"},
|
|
})
|
|
if err != nil {
|
|
log.Warningf("invalid request: %v", err)
|
|
return err
|
|
}
|
|
|
|
flavor := blob["flavor"]
|
|
bf := bundler.Ubiquitous
|
|
if flavor != "" {
|
|
bf = bundler.BundleFlavor(flavor)
|
|
}
|
|
log.Infof("request for flavor %v", bf)
|
|
|
|
var result *bundler.Bundle
|
|
switch matched[0] {
|
|
case "domain":
|
|
bundle, err := h.bundler.BundleFromRemote(blob["domain"], blob["ip"], bf)
|
|
if err != nil {
|
|
log.Warningf("couldn't bundle from remote: %v", err)
|
|
return err
|
|
}
|
|
result = bundle
|
|
case "certificate":
|
|
bundle, err := h.bundler.BundleFromPEMorDER([]byte(blob["certificate"]), []byte(blob["private_key"]), bf, "")
|
|
if err != nil {
|
|
log.Warning("bad PEM certifcate or private key")
|
|
return err
|
|
}
|
|
|
|
serverName := blob["domain"]
|
|
ip := blob["ip"]
|
|
|
|
if serverName != "" {
|
|
err := bundle.Cert.VerifyHostname(serverName)
|
|
if err != nil {
|
|
return errors.Wrap(errors.CertificateError, errors.VerifyFailed, err)
|
|
}
|
|
|
|
}
|
|
|
|
if ip != "" {
|
|
err := bundle.Cert.VerifyHostname(ip)
|
|
if err != nil {
|
|
return errors.Wrap(errors.CertificateError, errors.VerifyFailed, err)
|
|
}
|
|
}
|
|
|
|
result = bundle
|
|
}
|
|
log.Info("wrote response")
|
|
return api.SendResponse(w, result)
|
|
}
|