universal.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  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 defined in the
  55. // universal_signers*.go files. These activate
  56. // and deactivate signers based on build
  57. // flags; for example,
  58. // universal_signers_pkcs11.go contains a list
  59. // of valid signers when PKCS #11 is turned
  60. // on.
  61. for _, possibleSigner := range localSignerList {
  62. s, shouldProvide, err = possibleSigner(&root, policy)
  63. if shouldProvide {
  64. break
  65. }
  66. }
  67. if s == nil {
  68. err = cferr.New(cferr.PrivateKeyError, cferr.Unknown)
  69. }
  70. return s, err
  71. }
  72. func newUniversalSigner(root Root, policy *config.Signing) (*Signer, error) {
  73. ls, err := newLocalSigner(root, policy)
  74. if err != nil {
  75. return nil, err
  76. }
  77. rs, err := remote.NewSigner(policy)
  78. if err != nil {
  79. return nil, err
  80. }
  81. s := &Signer{
  82. policy: policy,
  83. local: ls,
  84. remote: rs,
  85. }
  86. return s, err
  87. }
  88. // NewSigner generates a new certificate signer from a Root structure.
  89. // This is one of two standard signers: local or remote. If the root
  90. // structure specifies a force remote, then a remote signer is created,
  91. // otherwise either a remote or local signer is generated based on the
  92. // policy. For a local signer, the CertFile and KeyFile need to be
  93. // defined in Root.
  94. func NewSigner(root Root, policy *config.Signing) (signer.Signer, error) {
  95. if policy == nil {
  96. policy = &config.Signing{
  97. Profiles: map[string]*config.SigningProfile{},
  98. Default: config.DefaultConfig(),
  99. }
  100. }
  101. if !policy.Valid() {
  102. return nil, cferr.New(cferr.PolicyError, cferr.InvalidPolicy)
  103. }
  104. var s signer.Signer
  105. var err error
  106. if root.ForceRemote {
  107. s, err = remote.NewSigner(policy)
  108. } else {
  109. if policy.NeedsLocalSigner() && policy.NeedsRemoteSigner() {
  110. s, err = newUniversalSigner(root, policy)
  111. } else {
  112. if policy.NeedsLocalSigner() {
  113. s, err = newLocalSigner(root, policy)
  114. }
  115. if policy.NeedsRemoteSigner() {
  116. s, err = remote.NewSigner(policy)
  117. }
  118. }
  119. }
  120. return s, err
  121. }
  122. // getMatchingProfile returns the SigningProfile that matches the profile passed.
  123. // if an empty profile string is passed it returns the default profile.
  124. func (s *Signer) getMatchingProfile(profile string) (*config.SigningProfile, error) {
  125. if profile == "" {
  126. return s.policy.Default, nil
  127. }
  128. for p, signingProfile := range s.policy.Profiles {
  129. if p == profile {
  130. return signingProfile, nil
  131. }
  132. }
  133. return nil, cferr.New(cferr.PolicyError, cferr.UnknownProfile)
  134. }
  135. // Sign sends a signature request to either the remote or local signer,
  136. // receiving a signed certificate or an error in response.
  137. func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) {
  138. profile, err := s.getMatchingProfile(req.Profile)
  139. if err != nil {
  140. return cert, err
  141. }
  142. if profile.RemoteServer != "" {
  143. return s.remote.Sign(req)
  144. }
  145. return s.local.Sign(req)
  146. }
  147. // Info sends an info request to the remote or local CFSSL server
  148. // receiving an Resp struct or an error in response.
  149. func (s *Signer) Info(req info.Req) (resp *info.Resp, err error) {
  150. profile, err := s.getMatchingProfile(req.Profile)
  151. if err != nil {
  152. return resp, err
  153. }
  154. if profile.RemoteServer != "" {
  155. return s.remote.Info(req)
  156. }
  157. return s.local.Info(req)
  158. }
  159. // SetDBAccessor sets the signer's cert db accessor.
  160. func (s *Signer) SetDBAccessor(dba certdb.Accessor) {
  161. s.local.SetDBAccessor(dba)
  162. }
  163. // GetDBAccessor returns the signer's cert db accessor.
  164. func (s *Signer) GetDBAccessor() certdb.Accessor {
  165. return s.local.GetDBAccessor()
  166. }
  167. // SetReqModifier sets the function to call to modify the HTTP request prior to sending it
  168. func (s *Signer) SetReqModifier(mod func(*http.Request, []byte)) {
  169. s.local.SetReqModifier(mod)
  170. s.remote.SetReqModifier(mod)
  171. }
  172. // SigAlgo returns the RSA signer's signature algorithm.
  173. func (s *Signer) SigAlgo() x509.SignatureAlgorithm {
  174. if s.local != nil {
  175. return s.local.SigAlgo()
  176. }
  177. // currently remote.SigAlgo just returns
  178. // x509.UnknownSignatureAlgorithm.
  179. return s.remote.SigAlgo()
  180. }
  181. // SetPolicy sets the signer's signature policy.
  182. func (s *Signer) SetPolicy(policy *config.Signing) {
  183. s.policy = policy
  184. }
  185. // Policy returns the signer's policy.
  186. func (s *Signer) Policy() *config.Signing {
  187. return s.policy
  188. }