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