Skip to content
This repository has been archived by the owner on Nov 22, 2022. It is now read-only.

Commit

Permalink
add support for client certificates
Browse files Browse the repository at this point in the history
Add options that allow client certificate and key file paths to be set.
This allows us to implement mutual TLS auth.
  • Loading branch information
hexagonal-sun committed Jul 20, 2021
1 parent f7c7d6e commit 036239b
Showing 1 changed file with 55 additions and 1 deletion.
56 changes: 55 additions & 1 deletion api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,56 @@ func NewClientWithCustomCA(host, token, caFile string, isGraphQL bool) (*Client,
return apiClient, err
}

// NewClientWithCustomCAClientCert initializes the global api client with a self-signed certificate and client certificates
func NewClientWithCustomCAClientCert(host, token, caFile string, certFile string, keyFile string, isGraphQL bool) (*Client, error) {
apiClient.host = host
apiClient.token = token
apiClient.caFile = caFile
apiClient.isGraphQL = isGraphQL

if apiClient.httpClientOverride == nil {
caCert, err := ioutil.ReadFile(apiClient.caFile)
if err != nil {
return nil, fmt.Errorf("error reading cert file: %w", err)
}
// use system cert pool as a baseline
caCertPool, err := x509.SystemCertPool()
if err != nil {
return nil, err
}
caCertPool.AppendCertsFromPEM(caCert)

clientCert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
return nil, err
}

clientCerts := []tls.Certificate{ clientCert }

apiClient.httpClient = &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext,
ForceAttemptHTTP2: true,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
TLSClientConfig: &tls.Config{
RootCAs: caCertPool,
Certificates: clientCerts,
},
},
}
}
apiClient.refreshLabInstance = true
err := apiClient.NewLab()
return apiClient, err
}

// NewClientWithCfg initializes the global api with the config data
func NewClientWithCfg(repoHost string, cfg config.Config, isGraphQL bool) (client *Client, err error) {
if repoHost == "" {
Expand All @@ -198,7 +248,11 @@ func NewClientWithCfg(repoHost string, cfg config.Config, isGraphQL bool) (clien
tlsVerify, _ := cfg.Get(repoHost, "skip_tls_verify")
skipTlsVerify := tlsVerify == "true" || tlsVerify == "1"
caCert, _ := cfg.Get(repoHost, "ca_cert")
if caCert != "" {
clientCert, _ := cfg.Get(repoHost, "client_cert")
keyFile, _ := cfg.Get(repoHost, "client_key")
if caCert != "" && clientCert != "" && keyFile != "" {
client, err = NewClientWithCustomCAClientCert(apiHost, token, caCert, clientCert, keyFile, isGraphQL)
} else if caCert != "" {
client, err = NewClientWithCustomCA(apiHost, token, caCert, isGraphQL)
} else {
client, err = NewClient(apiHost, token, skipTlsVerify, isGraphQL)
Expand Down

0 comments on commit 036239b

Please sign in to comment.