// Handle accepts client information requests, and uses the label to // look up the signer whose public certificate should be retrieved. If // the label is empty, the default label is used. func (h *MultiHandler) Handle(w http.ResponseWriter, r *http.Request) error { req := new(info.Req) body, err := ioutil.ReadAll(r.Body) if err != nil { log.Warningf("failed to read request body: %v", err) return errors.NewBadRequest(err) } err = json.Unmarshal(body, req) if err != nil { log.Warningf("failed to unmarshal request: %v", err) return errors.NewBadRequest(err) } log.Debug("checking label") if req.Label == "" { req.Label = h.defaultLabel } if _, ok := h.signers[req.Label]; !ok { log.Warningf("request for invalid endpoint") return errors.NewBadRequestString("bad label") } log.Debug("getting info") resp, err := h.signers[req.Label].Info(*req) if err != nil { log.Infof("error getting certificate: %v", err) return err } response := api.NewSuccessResponse(resp) w.Header().Set("Content-Type", "application/json") enc := json.NewEncoder(w) return enc.Encode(response) }
// Handle listens for incoming requests for CA information, and returns // a list containing information on each root certificate. func (h *Handler) Handle(w http.ResponseWriter, r *http.Request) error { req := new(info.Req) body, err := ioutil.ReadAll(r.Body) if err != nil { log.Warningf("failed to read request body: %v", err) return errors.NewBadRequest(err) } r.Body.Close() err = json.Unmarshal(body, req) if err != nil { log.Warningf("failed to unmarshal request: %v", err) return errors.NewBadRequest(err) } resp, err := h.sign.Info(*req) if err != nil { return err } response := api.NewSuccessResponse(resp) w.Header().Set("Content-Type", "application/json") enc := json.NewEncoder(w) return enc.Encode(response) }
// initialCAHandler is an HTTP handler that accepts a JSON blob in the // same format as the CSR endpoint; this blob should contain the // identity information for the CA's root key. This endpoint is not // suitable for creating intermediate certificates. func initialCAHandler(w http.ResponseWriter, r *http.Request) error { log.Info("setting up initial CA handler") body, err := ioutil.ReadAll(r.Body) if err != nil { log.Warningf("failed to read request body: %v", err) return errors.NewBadRequest(err) } r.Body.Close() req := new(csr.CertificateRequest) req.KeyRequest = csr.NewBasicKeyRequest() err = json.Unmarshal(body, req) if err != nil { log.Warningf("failed to unmarshal request: %v", err) return errors.NewBadRequest(err) } cert, _, key, err := initca.New(req) if err != nil { log.Warningf("failed to initialise new CA: %v", err) return err } response := api.NewSuccessResponse(&NewCA{string(key), string(cert)}) enc := json.NewEncoder(w) err = enc.Encode(response) return err }
// scanHandler is an HTTP handler that accepts GET parameters for host (required) // family and scanner, and uses these to perform scans, returning a JSON blob result. func scanHandler(w http.ResponseWriter, r *http.Request) error { if err := r.ParseForm(); err != nil { log.Warningf("failed to parse body: %v", err) return errors.NewBadRequest(err) } family := r.Form.Get("family") scanner := r.Form.Get("scanner") ip := r.Form.Get("ip") host := r.Form.Get("host") if host == "" { log.Warningf("no host given") return errors.NewBadRequestString("no host given") } results, err := scan.Default.RunScans(host, ip, family, scanner, 0) if err != nil { log.Warningf("%v", err) return errors.NewBadRequest(err) } response := api.NewSuccessResponse(results) enc := json.NewEncoder(w) return enc.Encode(response) }
// Handle responds to requests for the CA to generate a new private // key and certificate request on behalf of the client. The format for // these requests is documented in the API documentation. func (g *GeneratorHandler) Handle(w http.ResponseWriter, r *http.Request) error { log.Info("request for CSR") req := new(csr.CertificateRequest) body, err := ioutil.ReadAll(r.Body) if err != nil { log.Warningf("failed to read request body: %v", err) return errors.NewBadRequest(err) } err = json.Unmarshal(body, req) if err != nil { log.Warningf("failed to unmarshal request: %v", err) return errors.NewBadRequest(err) } key, csr, err := g.generator.ProcessRequest(req) if err != nil { log.Warningf("failed to process CSR: %v", err) // The validator returns a *cfssl/errors.HttpError return err } // Both key and csr are returned PEM-encoded. response := newSuccessResponse(&CertRequest{string(key), string(csr)}) w.Header().Set("Content-Type", "application/json") enc := json.NewEncoder(w) err = enc.Encode(response) return err }
// scanHandler is an HTTP handler that accepts GET parameters for host (required) // family and scanner, and uses these to perform scans, returning a JSON blob result. func scanHandler(w http.ResponseWriter, r *http.Request) error { if err := r.ParseForm(); err != nil { log.Warningf("failed to parse body: %v", err) return errors.NewBadRequest(err) } if len(r.Form["host"]) == 0 { log.Warningf("no host given") return errors.NewBadRequestString("no host given") } host := r.Form["host"][0] var family, scanner string if len(r.Form["family"]) > 0 { family = r.Form["family"][0] } if len(r.Form["scanner"]) > 0 { scanner = r.Form["scanner"][0] } results, err := scan.Default.RunScans(host, family, scanner) if err != nil { log.Warningf("%v", err) return errors.NewBadRequest(err) } response := api.NewSuccessResponse(results) enc := json.NewEncoder(w) return enc.Encode(response) }
func (rcg *RemoteCertGeneratorHandler) Handle(w http.ResponseWriter, r *http.Request) error { req := new(genSignRequest) body, err := ioutil.ReadAll(r.Body) if err != nil { log.Warningf("failed to read request body: %v", err) return errors.NewBadRequest(err) } err = json.Unmarshal(body, req) if err != nil { log.Warningf("failed to unmarshal request: %v", err) return errors.NewBadRequest(err) } csrPEM, key, err := rcg.generator.ProcessRequest(req.Request) if err != nil { log.Warningf("failed to process CSR: %v", err) // The validator returns a *cfssl/errors.HttpError return err } certPEM, err := rcg.remote.Sign(req.Hostname, csrPEM, req.Profile) if err != nil { log.Warningf("failed to send CSR to remote signer: %v", err) return err } result := map[string]string{ "private_key": string(key), "certificate": string(certPEM), } return sendResponse(w, result) }
func infoMain(args []string, c cli.Config) (err error) { if len(args) > 0 { return goerr.New("argument is provided but not defined; please refer to the usage by flag -h.") } var resp *info.Resp if c.Remote != "" { resp, err = getInfoFromRemote(c) if err != nil { return } } else if c.CFG != nil { resp, err = getInfoFromConfig(c) if err != nil { return } } else { return goerr.New("Either -remote or -config must be given. Refer to cfssl info -h for usage.") } respJSON, err := json.Marshal(resp) if err != nil { return errors.NewBadRequest(err) } fmt.Print(string(respJSON)) return nil }
// Handle responds to requests for the CA to generate a new private // key and certificate request on behalf of the client. The format for // these requests is documented in the API documentation. func (g *Handler) Handle(w http.ResponseWriter, r *http.Request) error { log.Info("request for CSR") body, err := ioutil.ReadAll(r.Body) if err != nil { log.Warningf("failed to read request body: %v", err) return errors.NewBadRequest(err) } r.Body.Close() req := new(csr.CertificateRequest) req.KeyRequest = csr.NewBasicKeyRequest() err = json.Unmarshal(body, req) if err != nil { log.Warningf("failed to unmarshal request: %v", err) return errors.NewBadRequest(err) } if req.CA != nil { log.Warningf("request received with CA section") return errors.NewBadRequestString("ca section only permitted in initca") } csr, key, err := g.generator.ProcessRequest(req) if err != nil { log.Warningf("failed to process CSR: %v", err) // The validator returns a *cfssl/errors.HttpError return err } sum, err := computeSum(csr) if err != nil { return errors.NewBadRequest(err) } // Both key and csr are returned PEM-encoded. response := api.NewSuccessResponse(&CertRequest{ Key: string(key), CSR: string(csr), Sums: map[string]Sum{"certificate_request": sum}, }) w.Header().Set("Content-Type", "application/json") enc := json.NewEncoder(w) err = enc.Encode(response) return err }
func (h *BundlerHandler) Handle(w http.ResponseWriter, r *http.Request) error { blob, matched, err := processRequestOneOf(r, [][]string{ {"domain"}, {"certificate"}, }) if err != nil { log.Warningf("invalid request: %v", err) return err } var result *bundler.Bundle switch matched[0] { case "domain": bundle, err := h.bundler.BundleFromRemote(blob["domain"], blob["ip"]) if err != nil { log.Warningf("couldn't bundle from remote: %v", err) return errors.NewBadRequest(err) } result = bundle case "certificate": flavor := blob["flavor"] var bf bundler.BundleFlavor = bundler.Ubiquitous if flavor != "" { bf = bundler.BundleFlavor(flavor) } bundle, err := h.bundler.BundleFromPEM([]byte(blob["certificate"]), []byte(blob["private_key"]), bf) if err != nil { log.Warning("bad PEM certifcate or private key") return errors.NewBadRequest(err) } log.Infof("request for flavour %v", flavor) result = bundle } response := newSuccessResponse(result) w.Header().Set("Content-Type", "application/json") enc := json.NewEncoder(w) err = enc.Encode(response) return err }
// scanHandler is an HTTP handler that accepts GET parameters for host (required) // family and scanner, and uses these to perform scans, returning a JSON blob result. func scanHandler(w http.ResponseWriter, r *http.Request) error { if err := r.ParseForm(); err != nil { log.Warningf("failed to parse body: %v", err) return errors.NewBadRequest(err) } family := r.Form.Get("family") scanner := r.Form.Get("scanner") ip := r.Form.Get("ip") timeoutStr := r.Form.Get("timeout") var timeout time.Duration var err error if timeoutStr != "" { if timeout, err = time.ParseDuration(timeoutStr); err != nil { return errors.NewBadRequest(err) } if timeout < time.Second || timeout > 5*time.Minute { return errors.NewBadRequestString("invalid timeout given") } } else { timeout = time.Minute } host := r.Form.Get("host") if host == "" { log.Warningf("no host given") return errors.NewBadRequestString("no host given") } results, err := scan.Default.RunScans(host, ip, family, scanner, timeout) if err != nil { return errors.NewBadRequest(err) } return json.NewEncoder(w).Encode(api.NewSuccessResponse(results)) }
// Handle responds to requests for the CA to sign the certificate // present in the "cert" parameter for the host named in the "hostname" // parameter. The certificate should be PEM-encoded. func (h *SignHandler) Handle(w http.ResponseWriter, r *http.Request) error { log.Info("signature request received") blob, err := processRequestRequired(r, []string{"hostname", "certificate_request"}) if err != nil { return err } certificate := []byte(blob["certificate_request"]) cert, err := h.signer.Sign(blob["hostname"], certificate, blob["profile"]) if err != nil { log.Warningf("failed to sign request: %v", err) return errors.NewBadRequest(err) } result := map[string]string{"certificate": string(cert)} log.Info("wrote response") return sendResponse(w, result) }
// Handle responds to requests for the CA to generate a new private // key and certificate on behalf of the client. The format for these // requests is documented in the API documentation. func (cg *CertGeneratorHandler) Handle(w http.ResponseWriter, r *http.Request) error { log.Info("request for CSR") req := new(genSignRequest) req.Request = csr.New() body, err := ioutil.ReadAll(r.Body) if err != nil { log.Warningf("failed to read request body: %v", err) return errors.NewBadRequest(err) } err = json.Unmarshal(body, req) if err != nil { log.Warningf("failed to unmarshal request: %v", err) return errors.NewBadRequest(err) } if req.Request == nil { log.Warning("empty request received") return errors.NewBadRequestString("missing request section") } if req.Request.CA != nil { log.Warningf("request received with CA section") return errors.NewBadRequestString("ca section only permitted in initca") } csr, key, err := cg.generator.ProcessRequest(req.Request) if err != nil { log.Warningf("failed to process CSR: %v", err) // The validator returns a *cfssl/errors.HttpError return err } signReq := signer.SignRequest{ Request: string(csr), Profile: req.Profile, Label: req.Label, } certBytes, err := cg.signer.Sign(signReq) if err != nil { log.Warningf("failed to sign request: %v", err) return err } reqSum, err := computeSum(csr) if err != nil { return errors.NewBadRequest(err) } certSum, err := computeSum(certBytes) if err != nil { return errors.NewBadRequest(err) } var file string if req.Format.Type == "pkcs12" { var password []byte if req.Format.Password != "" { password = []byte(req.Format.Password) } file = pkcs12.ParseAndEncode(key, certBytes, password) } result := map[string]interface{}{ "private_key": string(key), "certificate_request": string(csr), "certificate": string(certBytes), "format": file, "sums": map[string]Sum{ "certificate_request": reqSum, "certificate": certSum, }, } if len(req.Request.Hosts) == 0 { return api.SendResponseWithMessage(w, result, CSRNoHostMessage, errors.New(errors.PolicyError, errors.InvalidRequest).ErrorCode) } return api.SendResponse(w, result) }
// Handle responds to requests for the CA to generate a new private // key and certificate on behalf of the client. The format for these // requests is documented in the API documentation. func (cg *CertGeneratorHandler) Handle(w http.ResponseWriter, r *http.Request) error { log.Info("request for CSR") req := new(genSignRequest) body, err := ioutil.ReadAll(r.Body) if err != nil { log.Warningf("failed to read request body: %v", err) return errors.NewBadRequest(err) } err = json.Unmarshal(body, req) if err != nil { log.Warningf("failed to unmarshal request: %v", err) return errors.NewBadRequest(err) } if req.Request == nil { log.Warning("empty request received") return errors.NewBadRequestString("missing request section") } if req.Request.CA != nil { log.Warningf("request received with CA section") return errors.NewBadRequestString("ca section only permitted in initca") } csr, key, err := cg.generator.ProcessRequest(req.Request) if err != nil { log.Warningf("failed to process CSR: %v", err) // The validator returns a *cfssl/errors.HttpError return err } signReq := signer.SignRequest{ Request: string(csr), Profile: req.Profile, Label: req.Label, } certBytes, err := cg.signer.Sign(signReq) if err != nil { log.Warningf("failed to sign request: %v", err) return err } reqSum, err := computeSum(csr) if err != nil { return errors.NewBadRequest(err) } certSum, err := computeSum(certBytes) if err != nil { return errors.NewBadRequest(err) } result := map[string]interface{}{ "private_key": string(key), "certificate_request": string(csr), "certificate": string(certBytes), "sums": map[string]Sum{ "certificate_request": reqSum, "certificate": certSum, }, } return api.SendResponse(w, result) }
// Handle receives the incoming request, validates it, and processes it. func (h *AuthHandler) Handle(w http.ResponseWriter, r *http.Request) error { log.Info("signature request received") body, err := ioutil.ReadAll(r.Body) if err != nil { log.Errorf("failed to read response body: %v", err) return err } r.Body.Close() var aReq auth.AuthenticatedRequest err = json.Unmarshal(body, &aReq) if err != nil { log.Errorf("failed to unmarshal authenticated request: %v", err) return errors.NewBadRequest(err) } var req jsonSignRequest err = json.Unmarshal(aReq.Request, &req) if err != nil { log.Errorf("failed to unmarshal request from authenticated request: %v", err) return errors.NewBadRequestString("Unable to parse authenticated sign request") } // Sanity checks to ensure that we have a valid policy. This // should have been checked in NewAuthHandler. policy := h.signer.Policy() if policy == nil { log.Critical("signer was initialised without a signing policy") return errors.NewBadRequestString("invalid policy") } profile, err := signer.Profile(h.signer, req.Profile) if err != nil { return err } if profile.Provider == nil { log.Error("profile has no authentication provider") return errors.NewBadRequestString("no authentication provider") } if !profile.Provider.Verify(&aReq) { log.Warning("received authenticated request with invalid token") return errors.NewBadRequestString("invalid token") } signReq := jsonReqToTrue(req) if signReq.Request == "" { return errors.NewBadRequestString("missing parameter 'certificate_request'") } cert, err := h.signer.Sign(signReq) if err != nil { log.Errorf("signature failed: %v", err) return err } result := map[string]string{"certificate": string(cert)} log.Info("wrote response") return api.SendResponse(w, result) }
// Handle responds to requests for the CA to generate a new private // key and certificate on behalf of the client. The format for these // requests is documented in the API documentation. func (cg *CertGeneratorHandler) Handle(w http.ResponseWriter, r *http.Request) error { log.Info("request for CSR") req := new(genSignRequest) req.Request = csr.New() body, err := ioutil.ReadAll(r.Body) if err != nil { log.Warningf("failed to read request body: %v", err) return errors.NewBadRequest(err) } r.Body.Close() err = json.Unmarshal(body, req) if err != nil { log.Warningf("failed to unmarshal request: %v", err) return errors.NewBadRequest(err) } if req.Request == nil { log.Warning("empty request received") return errors.NewBadRequestString("missing request section") } if req.Request.CA != nil { log.Warningf("request received with CA section") return errors.NewBadRequestString("ca section only permitted in initca") } csr, key, err := cg.generator.ProcessRequest(req.Request) if err != nil { log.Warningf("failed to process CSR: %v", err) // The validator returns a *cfssl/errors.HttpError return err } signReq := signer.SignRequest{ Request: string(csr), Profile: req.Profile, Label: req.Label, } certBytes, err := cg.signer.Sign(signReq) if err != nil { log.Warningf("failed to sign request: %v", err) return err } reqSum, err := computeSum(csr) if err != nil { return errors.NewBadRequest(err) } certSum, err := computeSum(certBytes) if err != nil { return errors.NewBadRequest(err) } result := map[string]interface{}{ "private_key": string(key), "certificate_request": string(csr), "certificate": string(certBytes), "sums": map[string]Sum{ "certificate_request": reqSum, "certificate": certSum, }, } if req.Bundle { if cg.bundler == nil { return api.SendResponseWithMessage(w, result, NoBundlerMessage, errors.New(errors.PolicyError, errors.InvalidRequest).ErrorCode) } bundle, err := cg.bundler.BundleFromPEMorDER(certBytes, nil, bundler.Optimal, "") if err != nil { return err } result["bundle"] = bundle } if len(req.Request.Hosts) == 0 { return api.SendResponseWithMessage(w, result, CSRNoHostMessage, errors.New(errors.PolicyError, errors.InvalidRequest).ErrorCode) } return api.SendResponse(w, result) }