Add identity client and move identity to a new package.
This commit is contained in:
parent
9e7b86342b
commit
d85386d0b4
19 changed files with 667 additions and 86 deletions
105
ca/identity/client.go
Normal file
105
ca/identity/client.go
Normal file
|
@ -0,0 +1,105 @@
|
|||
package identity
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Client wraps http.Client with a transport using the step root and identity.
|
||||
type Client struct {
|
||||
CaURL *url.URL
|
||||
*http.Client
|
||||
}
|
||||
|
||||
// ResolveReference resolves the given reference from the CaURL.
|
||||
func (c *Client) ResolveReference(ref *url.URL) *url.URL {
|
||||
return c.CaURL.ResolveReference(ref)
|
||||
}
|
||||
|
||||
// LoadStepClient configures an http.Client with the root in
|
||||
// $STEPPATH/config/defaults.json and the identity defined in
|
||||
// $STEPPATH/config/identity.json
|
||||
func LoadClient() (*Client, error) {
|
||||
b, err := ioutil.ReadFile(DefaultsFile)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error reading %s", DefaultsFile)
|
||||
}
|
||||
|
||||
var defaults defaultsConfig
|
||||
if err := json.Unmarshal(b, &defaults); err != nil {
|
||||
return nil, errors.Wrapf(err, "error unmarshaling %s", DefaultsFile)
|
||||
}
|
||||
if err := defaults.Validate(); err != nil {
|
||||
return nil, errors.Wrapf(err, "error validating %s", DefaultsFile)
|
||||
}
|
||||
caURL, err := url.Parse(defaults.CaURL)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error validating %s", DefaultsFile)
|
||||
}
|
||||
if caURL.Scheme == "" {
|
||||
caURL.Scheme = "https"
|
||||
}
|
||||
|
||||
identity, err := LoadDefaultIdentity()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := identity.Validate(); err != nil {
|
||||
return nil, errors.Wrapf(err, "error validating %s", IdentityFile)
|
||||
}
|
||||
if kind := identity.Kind(); kind != MutualTLS {
|
||||
return nil, errors.Errorf("unsupported identity %s: only mTLS is currently supported", kind)
|
||||
}
|
||||
|
||||
// Prepare transport with information in defaults.json and identity.json
|
||||
tr := http.DefaultTransport.(*http.Transport).Clone()
|
||||
tr.TLSClientConfig = &tls.Config{}
|
||||
|
||||
// RootCAs
|
||||
b, err = ioutil.ReadFile(defaults.Root)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error loading %s", defaults.Root)
|
||||
}
|
||||
pool := x509.NewCertPool()
|
||||
if pool.AppendCertsFromPEM(b) {
|
||||
tr.TLSClientConfig.RootCAs = pool
|
||||
}
|
||||
|
||||
// Certificate
|
||||
crt, err := tls.LoadX509KeyPair(identity.Certificate, identity.Key)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error loading certificate: %v", err)
|
||||
}
|
||||
tr.TLSClientConfig.Certificates = []tls.Certificate{crt}
|
||||
|
||||
return &Client{
|
||||
CaURL: caURL,
|
||||
Client: &http.Client{
|
||||
Transport: tr,
|
||||
},
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
type defaultsConfig struct {
|
||||
CaURL string `json:"ca-url"`
|
||||
Root string `json:"root"`
|
||||
}
|
||||
|
||||
func (c *defaultsConfig) Validate() error {
|
||||
switch {
|
||||
case c.CaURL == "":
|
||||
return fmt.Errorf("missing or invalid `ca-url` property")
|
||||
case c.Root == "":
|
||||
return fmt.Errorf("missing or invalid `root` property")
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue