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  }