info.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // Package info implements the HTTP handler for the info command.
  2. package info
  3. import (
  4. "encoding/json"
  5. "io/ioutil"
  6. "net/http"
  7. "github.com/cloudflare/cfssl/api"
  8. "github.com/cloudflare/cfssl/errors"
  9. "github.com/cloudflare/cfssl/info"
  10. "github.com/cloudflare/cfssl/log"
  11. "github.com/cloudflare/cfssl/signer"
  12. )
  13. // Handler is a type that contains the root certificates for the CA,
  14. // and serves information on them for clients that need the certificates.
  15. type Handler struct {
  16. sign signer.Signer
  17. }
  18. // NewHandler creates a new handler to serve information on the CA's
  19. // certificates, taking a signer to use.
  20. func NewHandler(s signer.Signer) (http.Handler, error) {
  21. return &api.HTTPHandler{
  22. Handler: &Handler{
  23. sign: s,
  24. },
  25. Methods: []string{"POST"},
  26. }, nil
  27. }
  28. // Handle listens for incoming requests for CA information, and returns
  29. // a list containing information on each root certificate.
  30. func (h *Handler) Handle(w http.ResponseWriter, r *http.Request) error {
  31. req := new(info.Req)
  32. body, err := ioutil.ReadAll(r.Body)
  33. if err != nil {
  34. log.Warningf("failed to read request body: %v", err)
  35. return errors.NewBadRequest(err)
  36. }
  37. r.Body.Close()
  38. err = json.Unmarshal(body, req)
  39. if err != nil {
  40. log.Warningf("failed to unmarshal request: %v", err)
  41. return errors.NewBadRequest(err)
  42. }
  43. resp, err := h.sign.Info(*req)
  44. if err != nil {
  45. return err
  46. }
  47. response := api.NewSuccessResponse(resp)
  48. w.Header().Set("Content-Type", "application/json")
  49. enc := json.NewEncoder(w)
  50. return enc.Encode(response)
  51. }
  52. // MultiHandler is a handler for providing the public certificates for
  53. // a multi-root certificate authority. It takes a mapping of label to
  54. // signer and a default label, and handles the standard information
  55. // request as defined in the client package.
  56. type MultiHandler struct {
  57. signers map[string]signer.Signer
  58. defaultLabel string
  59. }
  60. // NewMultiHandler constructs a MultiHandler from a mapping of labels
  61. // to signers and the default label.
  62. func NewMultiHandler(signers map[string]signer.Signer, defaultLabel string) (http.Handler, error) {
  63. return &api.HTTPHandler{
  64. Handler: &MultiHandler{
  65. signers: signers,
  66. defaultLabel: defaultLabel,
  67. },
  68. Methods: []string{"POST"},
  69. }, nil
  70. }
  71. // Handle accepts client information requests, and uses the label to
  72. // look up the signer whose public certificate should be retrieved. If
  73. // the label is empty, the default label is used.
  74. func (h *MultiHandler) Handle(w http.ResponseWriter, r *http.Request) error {
  75. req := new(info.Req)
  76. body, err := ioutil.ReadAll(r.Body)
  77. if err != nil {
  78. log.Warningf("failed to read request body: %v", err)
  79. return errors.NewBadRequest(err)
  80. }
  81. r.Body.Close()
  82. err = json.Unmarshal(body, req)
  83. if err != nil {
  84. log.Warningf("failed to unmarshal request: %v", err)
  85. return errors.NewBadRequest(err)
  86. }
  87. log.Debug("checking label")
  88. if req.Label == "" {
  89. req.Label = h.defaultLabel
  90. }
  91. if _, ok := h.signers[req.Label]; !ok {
  92. log.Warningf("request for invalid endpoint")
  93. return errors.NewBadRequestString("bad label")
  94. }
  95. log.Debug("getting info")
  96. resp, err := h.signers[req.Label].Info(*req)
  97. if err != nil {
  98. log.Infof("error getting certificate: %v", err)
  99. return err
  100. }
  101. response := api.NewSuccessResponse(resp)
  102. w.Header().Set("Content-Type", "application/json")
  103. enc := json.NewEncoder(w)
  104. return enc.Encode(response)
  105. }