ocspsign.go 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // Package ocspsign implements the ocspsign command.
  2. package ocspsign
  3. import (
  4. "os"
  5. "time"
  6. "github.com/cloudflare/cfssl/cli"
  7. "github.com/cloudflare/cfssl/helpers"
  8. "github.com/cloudflare/cfssl/log"
  9. "github.com/cloudflare/cfssl/ocsp"
  10. )
  11. // Usage text of 'cfssl ocspsign'
  12. var ocspSignerUsageText = `cfssl ocspsign -- signs an OCSP response for a given CA, cert, and status.
  13. Returns a base64-encoded OCSP response.
  14. Usage of ocspsign:
  15. cfssl ocspsign -ca cert -responder cert -responder-key key -cert cert [-status status] [-reason code] [-revoked-at YYYY-MM-DD] [-interval 96h]
  16. Flags:
  17. `
  18. // Flags of 'cfssl ocspsign'
  19. var ocspSignerFlags = []string{"ca", "responder", "responder-key", "reason", "status", "revoked-at", "interval"}
  20. // ocspSignerMain is the main CLI of OCSP signer functionality.
  21. func ocspSignerMain(args []string, c cli.Config) (err error) {
  22. // Read the cert to be revoked from file
  23. certBytes, err := os.ReadFile(c.CertFile)
  24. if err != nil {
  25. log.Critical("Unable to read certificate: ", err)
  26. return
  27. }
  28. cert, err := helpers.ParseCertificatePEM(certBytes)
  29. if err != nil {
  30. log.Critical("Unable to parse certificate: ", err)
  31. return
  32. }
  33. req := ocsp.SignRequest{
  34. Certificate: cert,
  35. Status: c.Status,
  36. }
  37. if c.Status == "revoked" {
  38. var reasonCode int
  39. reasonCode, err = ocsp.ReasonStringToCode(c.Reason)
  40. if err != nil {
  41. log.Critical("Invalid reason code: ", err)
  42. return
  43. }
  44. req.Reason = reasonCode
  45. req.RevokedAt = time.Now()
  46. if c.RevokedAt != "now" {
  47. req.RevokedAt, err = time.Parse("2006-01-02", c.RevokedAt)
  48. if err != nil {
  49. log.Critical("Malformed revocation time: ", c.RevokedAt)
  50. return
  51. }
  52. }
  53. }
  54. s, err := SignerFromConfig(c)
  55. if err != nil {
  56. log.Critical("Unable to create OCSP signer: ", err)
  57. return
  58. }
  59. resp, err := s.Sign(req)
  60. if err != nil {
  61. log.Critical("Unable to sign OCSP response: ", err)
  62. return
  63. }
  64. cli.PrintOCSPResponse(resp)
  65. return
  66. }
  67. // SignerFromConfig creates a signer from a cli.Config as a helper for cli and serve
  68. func SignerFromConfig(c cli.Config) (ocsp.Signer, error) {
  69. // if this is called from serve then we need to use the specific responder key file
  70. // fallback to key for backwards-compatibility
  71. k := c.ResponderKeyFile
  72. if k == "" {
  73. k = c.KeyFile
  74. }
  75. return ocsp.NewSignerFromFile(c.CAFile, c.ResponderFile, k, time.Duration(c.Interval))
  76. }
  77. // Command assembles the definition of Command 'ocspsign'
  78. var Command = &cli.Command{UsageText: ocspSignerUsageText, Flags: ocspSignerFlags, Main: ocspSignerMain}