github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/cloudflare/cfssl/signer/remote/remote.go (about) 1 package remote 2 3 import ( 4 "encoding/json" 5 "errors" 6 "github.com/hellobchain/newcryptosm/http" 7 "github.com/hellobchain/newcryptosm/x509" 8 9 "github.com/hellobchain/third_party/cloudflare/cfssl/api/client" 10 "github.com/hellobchain/third_party/cloudflare/cfssl/certdb" 11 "github.com/hellobchain/third_party/cloudflare/cfssl/config" 12 cferr "github.com/hellobchain/third_party/cloudflare/cfssl/errors" 13 "github.com/hellobchain/third_party/cloudflare/cfssl/helpers" 14 "github.com/hellobchain/third_party/cloudflare/cfssl/info" 15 "github.com/hellobchain/third_party/cloudflare/cfssl/signer" 16 ) 17 18 // A Signer represents a CFSSL instance running as signing server. 19 // fulfills the signer.Signer interface 20 type Signer struct { 21 policy *config.Signing 22 reqModifier func(*http.Request, []byte) 23 } 24 25 // NewSigner creates a new remote Signer directly from a 26 // signing policy. 27 func NewSigner(policy *config.Signing) (*Signer, error) { 28 if policy != nil { 29 if !policy.Valid() { 30 return nil, cferr.New(cferr.PolicyError, 31 cferr.InvalidPolicy) 32 } 33 return &Signer{policy: policy}, nil 34 } 35 36 return nil, cferr.New(cferr.PolicyError, 37 cferr.InvalidPolicy) 38 } 39 40 // Sign sends a signature request to the remote CFSSL server, 41 // receiving a signed certificate or an error in response. The hostname, 42 // csr, and profileName are used as with a local signing operation, and 43 // the label is used to select a signing root in a multi-root CA. 44 func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) { 45 resp, err := s.remoteOp(req, req.Profile, "sign") 46 if err != nil { 47 return 48 } 49 if cert, ok := resp.([]byte); ok { 50 return cert, nil 51 } 52 return 53 } 54 55 // Info sends an info request to the remote CFSSL server, receiving an 56 // Resp struct or an error in response. 57 func (s *Signer) Info(req info.Req) (resp *info.Resp, err error) { 58 respInterface, err := s.remoteOp(req, req.Profile, "info") 59 if err != nil { 60 return 61 } 62 if resp, ok := respInterface.(*info.Resp); ok { 63 return resp, nil 64 } 65 return 66 } 67 68 // Helper function to perform a remote sign or info request. 69 func (s *Signer) remoteOp(req interface{}, profile, target string) (resp interface{}, err error) { 70 jsonData, err := json.Marshal(req) 71 if err != nil { 72 return nil, cferr.Wrap(cferr.APIClientError, cferr.JSONError, err) 73 } 74 75 p, err := signer.Profile(s, profile) 76 if err != nil { 77 return 78 } 79 80 server := client.NewServerTLS(p.RemoteServer, helpers.CreateTLSConfig(p.RemoteCAs, p.ClientCert)) 81 if server == nil { 82 return nil, cferr.Wrap(cferr.PolicyError, cferr.InvalidRequest, 83 errors.New("failed to connect to remote")) 84 } 85 86 server.SetReqModifier(s.reqModifier) 87 88 // There's no auth provider for the "info" method 89 if target == "info" { 90 resp, err = server.Info(jsonData) 91 } else if p.RemoteProvider != nil { 92 resp, err = server.AuthSign(jsonData, nil, p.RemoteProvider) 93 } else { 94 resp, err = server.Sign(jsonData) 95 } 96 97 if err != nil { 98 return nil, err 99 } 100 101 return 102 } 103 104 // SigAlgo returns the RSA signer's signature algorithm. 105 func (s *Signer) SigAlgo() x509.SignatureAlgorithm { 106 // TODO: implement this as a remote info call 107 return x509.UnknownSignatureAlgorithm 108 } 109 110 // SetPolicy sets the signer's signature policy. 111 func (s *Signer) SetPolicy(policy *config.Signing) { 112 s.policy = policy 113 } 114 115 // SetDBAccessor sets the signers' cert db accessor, currently noop. 116 func (s *Signer) SetDBAccessor(dba certdb.Accessor) { 117 // noop 118 } 119 120 // GetDBAccessor returns the signers' cert db accessor, currently noop. 121 func (s *Signer) GetDBAccessor() certdb.Accessor { 122 return nil 123 } 124 125 // SetReqModifier sets the function to call to modify the HTTP request prior to sending it 126 func (s *Signer) SetReqModifier(mod func(*http.Request, []byte)) { 127 s.reqModifier = mod 128 } 129 130 // Policy returns the signer's policy. 131 func (s *Signer) Policy() *config.Signing { 132 return s.policy 133 }