From 2a8c52d4ab4425ec9f73f7d893eeb610862bc3b6 Mon Sep 17 00:00:00 2001 From: Brian Rieger Date: Wed, 23 Mar 2022 13:29:01 -0500 Subject: [PATCH] Add in registry mutual tls --- pkg/imgpkg/cmd/registry_flags.go | 12 ++++++++++++ pkg/imgpkg/registry/registry.go | 24 +++++++++++++++++++++--- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/pkg/imgpkg/cmd/registry_flags.go b/pkg/imgpkg/cmd/registry_flags.go index 62586f513..769043196 100644 --- a/pkg/imgpkg/cmd/registry_flags.go +++ b/pkg/imgpkg/cmd/registry_flags.go @@ -17,6 +17,10 @@ type RegistryFlags struct { VerifyCerts bool Insecure bool + MutualTLS bool + ClientCertificate string + ClientKey string + Username string Password string Token string @@ -33,6 +37,10 @@ func (r *RegistryFlags) Set(cmd *cobra.Command) { cmd.Flags().BoolVar(&r.VerifyCerts, "registry-verify-certs", true, "Set whether to verify server's certificate chain and host name") cmd.Flags().BoolVar(&r.Insecure, "registry-insecure", false, "Allow the use of http when interacting with registries") + cmd.Flags().BoolVar(&r.MutualTLS, "registry-mutual-tls", false, "Set whether or not to use mutual TLS. If true set registry-client-cert-path and registry-client-key-path") + cmd.Flags().StringVar(&r.ClientCertificate, "registry-client-cert-path", "", "Add Client Cert to authenticate against registry with (format: /tmp/foo)") + cmd.Flags().StringVar(&r.ClientKey, "registry-client-key-path", "", "Add Client Key to authenticate against registry with (format: /tmp/foo)") + cmd.Flags().StringVar(&r.Username, "registry-username", "", "Set username for auth ($IMGPKG_USERNAME)") cmd.Flags().StringVar(&r.Password, "registry-password", "", "Set password for auth ($IMGPKG_PASSWORD)") cmd.Flags().StringVar(&r.Token, "registry-token", "", "Set token for auth ($IMGPKG_TOKEN)") @@ -71,6 +79,10 @@ func (r *RegistryFlags) AsRegistryOpts() registry.Opts { VerifyCerts: r.VerifyCerts, Insecure: r.Insecure, + MutualTLS: r.MutualTLS, + ClientCertificate: r.ClientCertificate, + ClientKey: r.ClientKey, + Username: r.Username, Password: r.Password, Token: r.Token, diff --git a/pkg/imgpkg/registry/registry.go b/pkg/imgpkg/registry/registry.go index 7e4dae379..0261c0538 100644 --- a/pkg/imgpkg/registry/registry.go +++ b/pkg/imgpkg/registry/registry.go @@ -30,6 +30,10 @@ type Opts struct { IncludeNonDistributableLayers bool + MutualTLS bool + ClientCertificate string + ClientKey string + Username string Password string Token string @@ -453,9 +457,23 @@ func newHTTPTransport(opts Opts) (*http.Transport, error) { clonedDefaultTransport := http.DefaultTransport.(*http.Transport).Clone() clonedDefaultTransport.ForceAttemptHTTP2 = false clonedDefaultTransport.ResponseHeaderTimeout = opts.ResponseHeaderTimeout - clonedDefaultTransport.TLSClientConfig = &tls.Config{ - RootCAs: pool, - InsecureSkipVerify: opts.VerifyCerts == false, + if opts.MutualTLS { + cert, err := tls.LoadX509KeyPair(opts.ClientCertificate, opts.ClientKey) + if err != nil { + return nil, fmt.Errorf("Failed to read client certificate or key from '%s' and '%s': %s", opts.ClientCertificate, opts.ClientKey, err) + } + certs := make([]tls.Certificate, 0) + certs = append(certs, cert) + clonedDefaultTransport.TLSClientConfig = &tls.Config{ + RootCAs: pool, + Certificates: certs, + InsecureSkipVerify: opts.VerifyCerts == false, + } + } else { + clonedDefaultTransport.TLSClientConfig = &tls.Config{ + RootCAs: pool, + InsecureSkipVerify: opts.VerifyCerts == false, + } } return clonedDefaultTransport, nil