fix: KES http2.0 communication support (#10341)

This commit is contained in:
Harshavardhana 2020-08-24 14:37:53 -07:00 committed by GitHub
parent 309b10f201
commit 03ec6adfd0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 46 additions and 26 deletions

View File

@ -16,6 +16,7 @@ package crypto
import (
"bytes"
"context"
"crypto/tls"
"crypto/x509"
"errors"
@ -115,15 +116,29 @@ func NewKes(cfg KesConfig) (KMS, error) {
if err != nil {
return nil, err
}
certPool, err := loadCACertificates(cfg.CAPath)
if err != nil {
if cfg.Transport.TLSClientConfig != nil {
if err = loadCACertificates(cfg.CAPath,
cfg.Transport.TLSClientConfig.RootCAs); err != nil {
return nil, err
}
} else {
rootCAs, _ := x509.SystemCertPool()
if rootCAs == nil {
// In some systems (like Windows) system cert pool is
// not supported or no certificates are present on the
// system - so we create a new cert pool.
rootCAs = x509.NewCertPool()
}
if err = loadCACertificates(cfg.CAPath, rootCAs); err != nil {
return nil, err
}
cfg.Transport.TLSClientConfig = &tls.Config{
Certificates: []tls.Certificate{cert},
RootCAs: certPool,
RootCAs: rootCAs,
}
cfg.Transport.ForceAttemptHTTP2 = true
}
cfg.Transport.TLSClientConfig.Certificates = []tls.Certificate{cert}
cfg.Transport.TLSClientConfig.NextProtos = []string{"h2"}
return &kesService{
client: &kesClient{
addr: cfg.Endpoint,
@ -359,7 +374,16 @@ func parseErrorResponse(resp *http.Response) error {
}
func (c *kesClient) post(url string, body io.Reader, limit int64) (io.Reader, error) {
resp, err := c.httpClient.Post(url, "application/json", body)
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, body)
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
resp, err := c.httpClient.Do(req)
if err != nil {
return nil, err
}
@ -388,7 +412,10 @@ func (c *kesClient) postRetry(url string, body io.ReadSeeker, limit int64) (io.R
return response, nil
}
if !xnet.IsNetworkOrHostDown(err) && !errors.Is(err, io.EOF) && !errors.Is(err, io.ErrUnexpectedEOF) {
if !xnet.IsNetworkOrHostDown(err) &&
!errors.Is(err, io.EOF) &&
!errors.Is(err, io.ErrUnexpectedEOF) &&
!errors.Is(err, context.DeadlineExceeded) {
return nil, err
}
@ -415,24 +442,17 @@ func (c *kesClient) postRetry(url string, body io.ReadSeeker, limit int64) (io.R
// file as PEM-encoded certificate and add it to
// the CertPool. If a file is not a PEM certificate
// it will be ignored.
func loadCACertificates(path string) (*x509.CertPool, error) {
rootCAs, _ := x509.SystemCertPool()
if rootCAs == nil {
// In some systems (like Windows) system cert pool is
// not supported or no certificates are present on the
// system - so we create a new cert pool.
rootCAs = x509.NewCertPool()
}
func loadCACertificates(path string, rootCAs *x509.CertPool) error {
if path == "" {
return rootCAs, nil
return nil
}
stat, err := os.Stat(path)
if err != nil {
if os.IsNotExist(err) || os.IsPermission(err) {
return rootCAs, nil
return nil
}
return nil, Errorf("crypto: cannot open '%s': %v", path, err)
return Errorf("crypto: cannot open '%s': %v", path, err)
}
// If path is a file, parse as PEM-encoded certifcate
@ -441,12 +461,12 @@ func loadCACertificates(path string) (*x509.CertPool, error) {
if !stat.IsDir() {
cert, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
return err
}
if !rootCAs.AppendCertsFromPEM(cert) {
return nil, Errorf("crypto: '%s' is not a valid PEM-encoded certificate", path)
return Errorf("crypto: '%s' is not a valid PEM-encoded certificate", path)
}
return rootCAs, nil
return nil
}
// If path is a directory then try
@ -456,7 +476,7 @@ func loadCACertificates(path string) (*x509.CertPool, error) {
// we ignore it.
files, err := ioutil.ReadDir(path)
if err != nil {
return nil, err
return err
}
for _, file := range files {
cert, err := ioutil.ReadFile(filepath.Join(path, file.Name()))
@ -465,6 +485,6 @@ func loadCACertificates(path string) (*x509.CertPool, error) {
}
rootCAs.AppendCertsFromPEM(cert) // ignore files which are not PEM certtificates
}
return rootCAs, nil
return nil
}