func getInfoFromRemote(c cli.Config) (resp *info.Resp, err error) { req := new(info.Req) req.Label = c.Label req.Profile = c.Profile cert, err := helpers.LoadClientCertificate(c.MutualTLSCertFile, c.MutualTLSKeyFile) if err != nil { return } remoteCAs, err := helpers.LoadPEMCertPool(c.TLSRemoteCAs) if err != nil { return } serv := client.NewServerTLS(c.Remote, helpers.CreateTLSConfig(remoteCAs, cert)) reqJSON, _ := json.Marshal(req) resp, err = serv.Info(reqJSON) if err != nil { return } _, err = helpers.ParseCertificatePEM([]byte(resp.Certificate)) if err != nil { return } return }
// Helper function to perform a remote sign or info request. func (s *Signer) remoteOp(req interface{}, profile, target string) (resp interface{}, err error) { jsonData, err := json.Marshal(req) if err != nil { return nil, cferr.Wrap(cferr.APIClientError, cferr.JSONError, err) } p, err := signer.Profile(s, profile) if err != nil { return } server := client.NewServerTLS(p.RemoteServer, helpers.CreateTLSConfig(p.RemoteCAs, p.ClientCert)) if server == nil { return nil, cferr.Wrap(cferr.PolicyError, cferr.InvalidRequest, errors.New("failed to connect to remote")) } // There's no auth provider for the "info" method if target == "info" { resp, err = server.Info(jsonData) } else if p.RemoteProvider != nil { resp, err = server.AuthSign(jsonData, nil, p.RemoteProvider) } else { resp, err = server.Sign(jsonData) } if err != nil { return nil, err } return }
// NewCFSSL produces a new CFSSL root. func NewCFSSL(metadata map[string]string) ([]*x509.Certificate, error) { host, ok := metadata["host"] if !ok { return nil, errors.New("transport: CFSSL root provider requires a host") } label := metadata["label"] profile := metadata["profile"] cert, err := helpers.LoadClientCertificate(metadata["mutual-tls-cert"], metadata["mutual-tls-key"]) if err != nil { return nil, err } remoteCAs, err := helpers.LoadPEMCertPool(metadata["tls-remote-ca"]) if err != nil { return nil, err } srv := client.NewServerTLS(host, helpers.CreateTLSConfig(remoteCAs, cert)) data, err := json.Marshal(info.Req{Label: label, Profile: profile}) if err != nil { return nil, err } resp, err := srv.Info(data) if err != nil { return nil, err } return helpers.ParseCertificatesPEM([]byte(resp.Certificate)) }
// NewCFSSLProvider takes the configuration information from an // Identity (and an optional default remote), returning a CFSSL // instance. There should be a profile in id called "cfssl", which // should contain label and profile fields as needed. func NewCFSSLProvider(id *core.Identity, defaultRemote client.Remote) (*CFSSL, error) { if id == nil { return nil, errors.New("transport: the identity hasn't been initialised. Has it been loaded from disk?") } cap := &CFSSL{ DefaultRemote: defaultRemote, } cfssl := id.Profiles["cfssl"] if cfssl != nil { cap.Label = cfssl["label"] cap.Profile = cfssl["profile"] if cap.DefaultRemote == nil { cert, err := helpers.LoadClientCertificate(cfssl["mutual-tls-cert"], cfssl["mutual-tls-key"]) if err != nil { return nil, err } remoteCAs, err := helpers.LoadPEMCertPool(cfssl["tls-remote-ca"]) if err != nil { return nil, err } cap.DefaultRemote = client.NewServerTLS(cfssl["remote"], helpers.CreateTLSConfig(remoteCAs, cert)) } cap.DefaultAuth.Type = cfssl["auth-type"] cap.DefaultAuth.Key = cfssl["auth-key"] } err := cap.setRemoteAndAuth() if err != nil { return nil, err } return cap, nil }
func (cap *CFSSL) setRemoteAndAuth() error { if cap.Label != "" { cfsslConfig := findLabel(cap.Label) profile, ok := getProfile(cfsslConfig, cap.Profile) if ok { remote, ok := getRemote(cfsslConfig, profile) if ok { cap.remote = client.NewServerTLS(remote, helpers.CreateTLSConfig(profile.RemoteCAs, profile.ClientCert)) cap.provider = profile.Provider return nil } // The profile may not have a remote set, but // it may have an authentication provider. cap.provider = profile.Provider } } cap.remote = cap.DefaultRemote if cap.provider != nil { return nil } return cap.loadAuth() }