Skip to content

Commit

Permalink
ostree: add plain MTLS support
Browse files Browse the repository at this point in the history
  • Loading branch information
lzap committed Oct 24, 2024
1 parent 2a3e608 commit 7554a32
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 41 deletions.
6 changes: 6 additions & 0 deletions cmd/build/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@ func resolvePipelineCommits(commitSources map[string][]ostree.SourceSpec) (map[s
commitSpecs := make([]ostree.CommitSpec, len(commitSources))
for idx, commitSource := range commitSources {
var err error
commitSource.MTLS = &ostree.MTLS{
CA: os.Getenv("OSBUILD_SOURCES_OSTREE_SSL_CA_CERT"),
ClientCert: os.Getenv("OSBUILD_SOURCES_OSTREE_SSL_CLIENT_CERT"),
ClientKey: os.Getenv("OSBUILD_SOURCES_OSTREE_SSL_CLIENT_KEY"),
}
commitSource.Proxy = os.Getenv("OSBUILD_SOURCES_OSTREE_PROXY")
commitSpecs[idx], err = ostree.Resolve(commitSource)
if err != nil {
return nil, err
Expand Down
6 changes: 6 additions & 0 deletions cmd/gen-manifests/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,12 @@ func resolvePipelineCommits(commitSources map[string][]ostree.SourceSpec) (map[s
commitSpecs := make([]ostree.CommitSpec, len(commitSources))
for idx, commitSource := range commitSources {
var err error
commitSource.MTLS = &ostree.MTLS{
CA: os.Getenv("OSBUILD_SOURCES_OSTREE_SSL_CA_CERT"),
ClientCert: os.Getenv("OSBUILD_SOURCES_OSTREE_SSL_CLIENT_CERT"),
ClientKey: os.Getenv("OSBUILD_SOURCES_OSTREE_SSL_CLIENT_KEY"),
}
commitSource.Proxy = os.Getenv("OSBUILD_SOURCES_OSTREE_PROXY")
commitSpecs[idx], err = ostree.Resolve(commitSource)
if err != nil {
return nil, err
Expand Down
11 changes: 10 additions & 1 deletion cmd/otk/osbuild-resolve-ostree-commit/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,16 @@ func run(r io.Reader, w io.Writer) error {
return err
}

sourceSpec := ostree.SourceSpec(inputTree.Tree)
var sourceSpec ostree.SourceSpec
sourceSpec.URL = inputTree.Tree.URL
sourceSpec.Ref = inputTree.Tree.Ref
sourceSpec.RHSM = inputTree.Tree.RHSM
sourceSpec.MTLS = &ostree.MTLS{
CA: os.Getenv("OSBUILD_SOURCES_OSTREE_SSL_CA_CERT"),
ClientCert: os.Getenv("OSBUILD_SOURCES_OSTREE_SSL_CLIENT_CERT"),
ClientKey: os.Getenv("OSBUILD_SOURCES_OSTREE_SSL_CLIENT_KEY"),
}
sourceSpec.Proxy = os.Getenv("OSBUILD_SOURCES_OSTREE_PROXY")

var commitSpec ostree.CommitSpec
if !underTest() {
Expand Down
7 changes: 7 additions & 0 deletions pkg/distro/fedora/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package fedora
import (
"fmt"
"math/rand"
"os"

"github.com/osbuild/images/internal/common"
"github.com/osbuild/images/internal/workload"
Expand Down Expand Up @@ -815,6 +816,12 @@ func makeOSTreeParentCommit(options *ostree.ImageOptions, defaultRef string) (*o
URL: options.URL,
Ref: parentRef,
RHSM: options.RHSM,
MTLS: &ostree.MTLS{
CA: os.Getenv("OSBUILD_SOURCES_OSTREE_SSL_CA_CERT"),
ClientCert: os.Getenv("OSBUILD_SOURCES_OSTREE_SSL_CLIENT_CERT"),
ClientKey: os.Getenv("OSBUILD_SOURCES_OSTREE_SSL_CLIENT_KEY"),
},
Proxy: os.Getenv("OSBUILD_SOURCES_OSTREE_PROXY"),
}
return parentCommit, commitRef
}
Expand Down
7 changes: 7 additions & 0 deletions pkg/distro/rhel/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package rhel
import (
"fmt"
"math/rand"
"os"

"github.com/osbuild/images/internal/workload"
"github.com/osbuild/images/pkg/blueprint"
Expand Down Expand Up @@ -782,6 +783,12 @@ func makeOSTreeParentCommit(options *ostree.ImageOptions, defaultRef string) (*o
URL: options.URL,
Ref: parentRef,
RHSM: options.RHSM,
MTLS: &ostree.MTLS{
CA: os.Getenv("OSBUILD_SOURCES_OSTREE_SSL_CA_CERT"),
ClientCert: os.Getenv("OSBUILD_SOURCES_OSTREE_SSL_CLIENT_CERT"),
ClientKey: os.Getenv("OSBUILD_SOURCES_OSTREE_SSL_CLIENT_KEY"),
},
Proxy: os.Getenv("OSBUILD_SOURCES_OSTREE_PROXY"),
}
return parentCommit, commitRef
}
Expand Down
102 changes: 64 additions & 38 deletions pkg/ostree/ostree.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,21 @@ var (
// SourceSpec serves as input for ResolveParams, and contains all necessary
// variables to resolve a ref, which can then be turned into a CommitSpec.
type SourceSpec struct {
URL string
Ref string
URL string
Ref string
// RHSM indicates to use RHSM secrets when pulling from the remote. Alternatively, you can use MTLS with plain certs.
RHSM bool
// MTLS information. Will be ignored if RHSM is set.
MTLS *MTLS
// Proxy as HTTP proxy to use when fetching the ref.
Proxy string
}

// MTLS contains the options for resolving an ostree source.
type MTLS struct {
CA string
ClientCert string
ClientKey string
}

// CommitSpec specifies an ostree commit using any combination of Ref (branch), URL (source), and Checksum (commit ID).
Expand Down Expand Up @@ -138,59 +150,53 @@ func verifyChecksum(commit string) bool {
return len(commit) > 0 && ostreeCommitRE.MatchString(commit)
}

// ResolveRef resolves the URL path specified by the location and ref
// resolveRef resolves the URL path specified by the location and ref
// (location+"refs/heads/"+ref) and returns the commit ID for the named ref. If
// there is an error, it will be of type ResolveRefError.
func resolveRef(location, ref string, consumerCerts bool, subs *rhsm.Subscriptions, ca *string) (string, error) {
u, err := url.Parse(location)
func resolveRef(ss SourceSpec) (string, error) {
u, err := url.Parse(ss.URL)
if err != nil {
return "", NewResolveRefError("error parsing ostree repository location: %v", err)
}
u.Path = path.Join(u.Path, "refs/heads/", ref)

var client *http.Client
if consumerCerts {
if subs == nil {
subs, err = rhsm.LoadSystemSubscriptions()
if err != nil {
return "", NewResolveRefError("error adding rhsm certificates when resolving ref: %s", err)
}
if subs.Consumer == nil {
return "", NewResolveRefError("error adding rhsm certificates when resolving ref")
}
}
u.Path = path.Join(u.Path, "refs/heads/", ss.Ref)

transport := http.DefaultTransport.(*http.Transport).Clone()
client := &http.Client{
Transport: transport,
Timeout: 300 * time.Second,
}
if u.Scheme == "https" {
tlsConf := &tls.Config{
MinVersion: tls.VersionTLS12,
}

if ca != nil {
caCertPEM, err := os.ReadFile(*ca)
// If CA is set, load the CA certificate and add it to the TLS configuration. Otherwise, use the system CA.
if ss.MTLS.CA != "" {
caCertPEM, err := os.ReadFile(ss.MTLS.CA)
if err != nil {
return "", NewResolveRefError("error adding rhsm certificates when resolving ref: %s", err)
return "", NewResolveRefError("error adding ca certificate when resolving ref: %s", err)
}
roots := x509.NewCertPool()
ok := roots.AppendCertsFromPEM(caCertPEM)
if !ok {
return "", NewResolveRefError("error adding rhsm certificates when resolving ref")
tlsConf.RootCAs = x509.NewCertPool()
if ok := tlsConf.RootCAs.AppendCertsFromPEM(caCertPEM); !ok {
return "", NewResolveRefError("error adding ca certificate when resolving ref")
}
tlsConf.RootCAs = roots
}

cert, err := tls.LoadX509KeyPair(subs.Consumer.ConsumerCert, subs.Consumer.ConsumerKey)
if err != nil {
return "", NewResolveRefError("error adding rhsm certificates when resolving ref: %s", err)
if ss.MTLS.ClientCert != "" && ss.MTLS.ClientKey != "" {
cert, err := tls.LoadX509KeyPair(ss.MTLS.ClientCert, ss.MTLS.ClientKey)
if err != nil {
return "", NewResolveRefError("error adding client certificate when resolving ref: %s", err)
}
tlsConf.Certificates = []tls.Certificate{cert}
}
tlsConf.Certificates = []tls.Certificate{cert}

client = &http.Client{
Transport: &http.Transport{
TLSClientConfig: tlsConf,
},
Timeout: 300 * time.Second,
transport.TLSClientConfig = tlsConf
}

if ss.Proxy != "" {
transport.Proxy = func(request *http.Request) (*url.URL, error) {
return url.Parse(ss.Proxy)
}
} else {
client = &http.Client{}
}

req, err := http.NewRequest(http.MethodGet, u.String(), nil)
Expand Down Expand Up @@ -235,7 +241,27 @@ func Resolve(source SourceSpec) (CommitSpec, error) {
}

if source.RHSM {
var subs *rhsm.Subscriptions
var err error

commit.Secrets = "org.osbuild.rhsm.consumer"
subs, err = rhsm.LoadSystemSubscriptions()

if err != nil {
return commit, NewResolveRefError("error adding rhsm certificates when resolving ref: %s", err)
}

if subs.Consumer == nil {
return commit, NewResolveRefError("error adding rhsm certificates when resolving ref")
}

if source.MTLS != nil {
return commit, NewResolveRefError("cannot use both RHSM and MTLS when resolving ref")
}

source.MTLS = &MTLS{}
source.MTLS.ClientCert = subs.Consumer.ConsumerCert
source.MTLS.ClientKey = subs.Consumer.ConsumerKey
}

if verifyChecksum(source.Ref) {
Expand All @@ -252,7 +278,7 @@ func Resolve(source SourceSpec) (CommitSpec, error) {
// URL set: Resolve checksum
if source.URL != "" {
// If a URL is specified, we need to fetch the commit at the URL.
checksum, err := resolveRef(source.URL, source.Ref, source.RHSM, nil, nil)
checksum, err := resolveRef(source)
if err != nil {
return CommitSpec{}, err // ResolveRefError
}
Expand Down
16 changes: 14 additions & 2 deletions pkg/ostree/ostree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,13 @@ func TestOstreeresolveRef(t *testing.T) {
{srvConf.Srv.URL, "valid/ostree/ref"}: goodRef,
}
for in, expOut := range validCases {
out, err := resolveRef(in.location, in.ref, srvConf.RHSM, srvConf.Subs, &mTLSSrv.CAPath)
out, err := resolveRef(SourceSpec{
in.location,
in.ref,
srvConf.RHSM,
&MTLS{mTLSSrv.CAPath, mTLSSrv.ClientCrtPath, mTLSSrv.ClientKeyPath},
"",
})
assert.NoError(t, err)
assert.Equal(t, expOut, out)
}
Expand All @@ -91,7 +97,13 @@ func TestOstreeresolveRef(t *testing.T) {
{srvConf.Srv.URL, "get_bad_ref"}: fmt.Sprintf("ostree repository \"%s/refs/heads/get_bad_ref\" returned invalid reference", srvConf.Srv.URL),
}
for in, expMsg := range errCases {
_, err := resolveRef(in.location, in.ref, srvConf.RHSM, srvConf.Subs, &mTLSSrv.CAPath)
_, err := resolveRef(SourceSpec{
in.location,
in.ref,
srvConf.RHSM,
&MTLS{mTLSSrv.CAPath, mTLSSrv.ClientCrtPath, mTLSSrv.ClientKeyPath},
"",
})
assert.EqualError(t, err, expMsg)
}
}
Expand Down

0 comments on commit 7554a32

Please sign in to comment.