universal.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. // Package universal implements a signer that can do remote or local
  2. package universal
  3. import (
  4. "crypto/x509"
  5. "net/http"
  6. "github.com/cloudflare/cfssl/certdb"
  7. "github.com/cloudflare/cfssl/config"
  8. cferr "github.com/cloudflare/cfssl/errors"
  9. "github.com/cloudflare/cfssl/info"
  10. "github.com/cloudflare/cfssl/signer"
  11. "github.com/cloudflare/cfssl/signer/local"
  12. "github.com/cloudflare/cfssl/signer/remote"
  13. )
  14. // Signer represents a universal signer which is both local and remote
  15. // to fulfill the signer.Signer interface.
  16. type Signer struct {
  17. local signer.Signer
  18. remote signer.Signer
  19. policy *config.Signing
  20. }
  21. // Root is used to define where the universal signer gets its public
  22. // certificate and private keys for signing.
  23. type Root struct {
  24. Config map[string]string
  25. ForceRemote bool
  26. }
  27. // a localSignerCheck looks at the Config keys in the Root, and
  28. // decides whether it has enough information to produce a signer.
  29. type localSignerCheck func(root *Root, policy *config.Signing) (signer.Signer, bool, error)
  30. // fileBackedSigner determines whether a file-backed local signer is supported.
  31. func fileBackedSigner(root *Root, policy *config.Signing) (signer.Signer, bool, error) {
  32. keyFile := root.Config["key-file"]
  33. certFile := root.Config["cert-file"]
  34. if keyFile == "" {
  35. return nil, false, nil
  36. }
  37. signer, err := local.NewSignerFromFile(certFile, keyFile, policy)
  38. return signer, true, err
  39. }
  40. var localSignerList = []localSignerCheck{
  41. fileBackedSigner,
  42. }
  43. // PrependLocalSignerToList prepends signer to the local signer's list
  44. func PrependLocalSignerToList(signer localSignerCheck) {
  45. localSignerList = append([]localSignerCheck{signer}, localSignerList...)
  46. }
  47. func newLocalSigner(root Root, policy *config.Signing) (s signer.Signer, err error) {
  48. // shouldProvide indicates whether the
  49. // function *should* have produced a key. If
  50. // it's true, we should use the signer and
  51. // error returned. Otherwise, keep looking for
  52. // signers.
  53. var shouldProvide bool
  54. // localSignerList is a list of signers defined
  55. // here or in the universal_signers*.go files.
  56. // These activate and deactivate signers based
  57. // on build flags.
  58. for _, possibleSigner := range localSignerList {
  59. s, shouldProvide, err = possibleSigner(&root, policy)
  60. if shouldProvide {
  61. break
  62. }
  63. }
  64. if s == nil {
  65. err = cferr.New(cferr.PrivateKeyError, cferr.Unknown)
  66. }
  67. return s, err
  68. }
  69. func newUniversalSigner(root Root, policy *config.Signing) (*Signer, error) {
  70. ls, err := newLocalSigner(root, policy)
  71. if err != nil {
  72. return nil, err
  73. }
  74. rs, err := remote.NewSigner(policy)
  75. if err != nil {
  76. return nil, err
  77. }
  78. s := &Signer{
  79. policy: policy,
  80. local: ls,
  81. remote: rs,
  82. }
  83. return s, err
  84. }
  85. // NewSigner generates a new certificate signer from a Root structure.
  86. // This is one of two standard signers: local or remote. If the root
  87. // structure specifies a force remote, then a remote signer is created,
  88. // otherwise either a remote or local signer is generated based on the
  89. // policy. For a local signer, the CertFile and KeyFile need to be
  90. // defined in Root.
  91. func NewSigner(root Root, policy *config.Signing) (signer.Signer, error) {
  92. if policy == nil {
  93. policy = &config.Signing{
  94. Profiles: map[string]*config.SigningProfile{},
  95. Default: config.DefaultConfig(),
  96. }
  97. }
  98. if !policy.Valid() {
  99. return nil, cferr.New(cferr.PolicyError, cferr.InvalidPolicy)
  100. }
  101. var s signer.Signer
  102. var err error
  103. if root.ForceRemote {
  104. s, err = remote.NewSigner(policy)
  105. } else {
  106. if policy.NeedsLocalSigner() && policy.NeedsRemoteSigner() {
  107. s, err = newUniversalSigner(root, policy)
  108. } else {
  109. if policy.NeedsLocalSigner() {
  110. s, err = newLocalSigner(root, policy)
  111. }
  112. if policy.NeedsRemoteSigner() {
  113. s, err = remote.NewSigner(policy)
  114. }
  115. }
  116. }
  117. return s, err
  118. }
  119. // getMatchingProfile returns the SigningProfile that matches the profile passed.
  120. // if an empty profile string is passed it returns the default profile.
  121. func (s *Signer) getMatchingProfile(profile string) (*config.SigningProfile, error) {
  122. if profile == "" {
  123. return s.policy.Default, nil
  124. }
  125. for p, signingProfile := range s.policy.Profiles {
  126. if p == profile {
  127. return signingProfile, nil
  128. }
  129. }
  130. return nil, cferr.New(cferr.PolicyError, cferr.UnknownProfile)
  131. }
  132. // Sign sends a signature request to either the remote or local signer,
  133. // receiving a signed certificate or an error in response.
  134. func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) {
  135. profile, err := s.getMatchingProfile(req.Profile)
  136. if err != nil {
  137. return cert, err
  138. }
  139. if profile.RemoteServer != "" {
  140. return s.remote.Sign(req)
  141. }
  142. return s.local.Sign(req)
  143. }
  144. // Info sends an info request to the remote or local CFSSL server
  145. // receiving an Resp struct or an error in response.
  146. func (s *Signer) Info(req info.Req) (resp *info.Resp, err error) {
  147. profile, err := s.getMatchingProfile(req.Profile)
  148. if err != nil {
  149. return resp, err
  150. }
  151. if profile.RemoteServer != "" {
  152. return s.remote.Info(req)
  153. }
  154. return s.local.Info(req)
  155. }
  156. // SetDBAccessor sets the signer's cert db accessor.
  157. func (s *Signer) SetDBAccessor(dba certdb.Accessor) {
  158. s.local.SetDBAccessor(dba)
  159. }
  160. // GetDBAccessor returns the signer's cert db accessor.
  161. func (s *Signer) GetDBAccessor() certdb.Accessor {
  162. return s.local.GetDBAccessor()
  163. }
  164. // SetReqModifier sets the function to call to modify the HTTP request prior to sending it
  165. func (s *Signer) SetReqModifier(mod func(*http.Request, []byte)) {
  166. s.local.SetReqModifier(mod)
  167. s.remote.SetReqModifier(mod)
  168. }
  169. // SigAlgo returns the RSA signer's signature algorithm.
  170. func (s *Signer) SigAlgo() x509.SignatureAlgorithm {
  171. if s.local != nil {
  172. return s.local.SigAlgo()
  173. }
  174. // currently remote.SigAlgo just returns
  175. // x509.UnknownSignatureAlgorithm.
  176. return s.remote.SigAlgo()
  177. }
  178. // SetPolicy sets the signer's signature policy.
  179. func (s *Signer) SetPolicy(policy *config.Signing) {
  180. s.policy = policy
  181. }
  182. // Policy returns the signer's policy.
  183. func (s *Signer) Policy() *config.Signing {
  184. return s.policy
  185. }