|
Packit Service |
509fd4 |
// +build integration
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
package main
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
import (
|
|
Packit Service |
509fd4 |
"crypto/tls"
|
|
Packit Service |
509fd4 |
"crypto/x509"
|
|
Packit Service |
509fd4 |
"encoding/json"
|
|
Packit Service |
509fd4 |
"errors"
|
|
Packit Service |
509fd4 |
"io/ioutil"
|
|
Packit Service |
509fd4 |
"net/http"
|
|
Packit Service |
509fd4 |
"testing"
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
"github.com/stretchr/testify/require"
|
|
Packit Service |
509fd4 |
)
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
const trustedCADir = "/etc/osbuild-composer-test/ca"
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
type connectionConfig struct {
|
|
Packit Service |
509fd4 |
CACertFile string
|
|
Packit Service |
509fd4 |
ClientKeyFile string
|
|
Packit Service |
509fd4 |
ClientCertFile string
|
|
Packit Service |
509fd4 |
}
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
func createTLSConfig(config *connectionConfig) (*tls.Config, error) {
|
|
Packit Service |
509fd4 |
caCertPEM, err := ioutil.ReadFile(config.CACertFile)
|
|
Packit Service |
509fd4 |
if err != nil {
|
|
Packit Service |
509fd4 |
return nil, err
|
|
Packit Service |
509fd4 |
}
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
roots := x509.NewCertPool()
|
|
Packit Service |
509fd4 |
ok := roots.AppendCertsFromPEM(caCertPEM)
|
|
Packit Service |
509fd4 |
if !ok {
|
|
Packit Service |
509fd4 |
return nil, errors.New("failed to append root certificate")
|
|
Packit Service |
509fd4 |
}
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
cert, err := tls.LoadX509KeyPair(config.ClientCertFile, config.ClientKeyFile)
|
|
Packit Service |
509fd4 |
if err != nil {
|
|
Packit Service |
509fd4 |
return nil, err
|
|
Packit Service |
509fd4 |
}
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
return &tls.Config{
|
|
Packit Service |
509fd4 |
RootCAs: roots,
|
|
Packit Service |
509fd4 |
Certificates: []tls.Certificate{cert},
|
|
Packit Service |
509fd4 |
}, nil
|
|
Packit Service |
509fd4 |
}
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
func TestWorkerAPIAuth(t *testing.T) {
|
|
Packit Service |
509fd4 |
t.Run("certificate signed by a trusted CA", func(t *testing.T) {
|
|
Packit Service |
509fd4 |
cases := []struct {
|
|
Packit Service |
509fd4 |
caseDesc string
|
|
Packit Service |
509fd4 |
subj string
|
|
Packit Service |
509fd4 |
addext string
|
|
Packit Service |
509fd4 |
success bool
|
|
Packit Service |
509fd4 |
}{
|
|
Packit Service |
509fd4 |
{"valid CN 1", "/CN=worker.osbuild.org/emailAddress=osbuild@example.com", "subjectAltName=DNS:example.com,DNS:worker.osbuild.org", true},
|
|
Packit Service |
509fd4 |
{"valid CN 2", "/CN=localhost/emailAddress=osbuild@example.com", "subjectAltName=DNS:example.com,DNS:localhost", true},
|
|
Packit Service |
509fd4 |
{"invalid CN", "/CN=example.com/emailAddress=osbuild@example.com", "subjectAltName=DNS:example.com", false},
|
|
Packit Service |
509fd4 |
}
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
authority := &ca{BaseDir: trustedCADir}
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
for _, c := range cases {
|
|
Packit Service |
509fd4 |
t.Run(c.caseDesc, func(t *testing.T) {
|
|
Packit Service |
509fd4 |
ckp, err := authority.newCertificateKeyPair(c.subj, osbuildClientExt, c.addext)
|
|
Packit Service |
509fd4 |
require.NoError(t, err)
|
|
Packit Service |
509fd4 |
defer ckp.remove()
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
testRoute(t, "https://localhost:8700/api/worker/v1/status", ckp, c.success)
|
|
Packit Service |
509fd4 |
})
|
|
Packit Service |
509fd4 |
}
|
|
Packit Service |
509fd4 |
})
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
t.Run("certificate signed by an untrusted CA", func(t *testing.T) {
|
|
Packit Service |
509fd4 |
// generate a new CA
|
|
Packit Service |
509fd4 |
ca, err := newCA("/CN=untrusted.osbuild.org")
|
|
Packit Service |
509fd4 |
require.NoError(t, err)
|
|
Packit Service |
509fd4 |
defer ca.remove()
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
// create a new certificate and signed it with the new CA
|
|
Packit Service |
509fd4 |
ckp, err := ca.newCertificateKeyPair("/CN=localhost/emailAddress=osbuild@example.com", osbuildClientExt, "")
|
|
Packit Service |
509fd4 |
require.NoError(t, err)
|
|
Packit Service |
509fd4 |
defer ckp.remove()
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
testRoute(t, "https://localhost:8700/api/worker/v1/status", ckp, false)
|
|
Packit Service |
509fd4 |
})
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
t.Run("self-signed certificate", func(t *testing.T) {
|
|
Packit Service |
509fd4 |
// generate a new self-signed certificate
|
|
Packit Service |
509fd4 |
ckp, err := newSelfSignedCertificateKeyPair("/CN=osbuild.org")
|
|
Packit Service |
509fd4 |
require.NoError(t, err)
|
|
Packit Service |
509fd4 |
defer ckp.remove()
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
testRoute(t, "https://localhost:8700/api/worker/v1/status", ckp, false)
|
|
Packit Service |
509fd4 |
})
|
|
Packit Service |
509fd4 |
}
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
func TestKojiAPIAuth(t *testing.T) {
|
|
Packit Service |
509fd4 |
t.Run("certificate signed by a trusted CA", func(t *testing.T) {
|
|
Packit Service |
509fd4 |
cases := []struct {
|
|
Packit Service |
509fd4 |
caseDesc string
|
|
Packit Service |
509fd4 |
subj string
|
|
Packit Service |
509fd4 |
addext string
|
|
Packit Service |
509fd4 |
success bool
|
|
Packit Service |
509fd4 |
}{
|
|
Packit Service |
509fd4 |
{"valid CN and SAN 1", "/CN=client.osbuild.org/emailAddress=osbuild@example.com", "subjectAltName=DNS:example.com,DNS:client.osbuild.org", true},
|
|
Packit Service |
509fd4 |
{"valid CN and SAN 2", "/CN=localhost/emailAddress=osbuild@example.com", "subjectAltName=DNS:example.com,DNS:localhost", true},
|
|
Packit Service |
509fd4 |
{"invalid CN and SAN", "/CN=example.com/emailAddress=osbuild@example.com", "subjectAltName=DNS:example.com", false},
|
|
Packit Service |
509fd4 |
}
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
authority := &ca{BaseDir: trustedCADir}
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
for _, c := range cases {
|
|
Packit Service |
509fd4 |
t.Run(c.caseDesc, func(t *testing.T) {
|
|
Packit Service |
509fd4 |
ckp, err := authority.newCertificateKeyPair(c.subj, osbuildClientExt, c.addext)
|
|
Packit Service |
509fd4 |
require.NoError(t, err)
|
|
Packit Service |
509fd4 |
defer ckp.remove()
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
testRoute(t, "https://localhost/api/composer-koji/v1/status", ckp, c.success)
|
|
Packit Service |
509fd4 |
})
|
|
Packit Service |
509fd4 |
}
|
|
Packit Service |
509fd4 |
})
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
t.Run("certificate signed by an untrusted CA", func(t *testing.T) {
|
|
Packit Service |
509fd4 |
// generate a new CA
|
|
Packit Service |
509fd4 |
ca, err := newCA("/CN=osbuild.org")
|
|
Packit Service |
509fd4 |
require.NoError(t, err)
|
|
Packit Service |
509fd4 |
defer ca.remove()
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
// create a new certificate and signed it with the new CA
|
|
Packit Service |
509fd4 |
ckp, err := ca.newCertificateKeyPair("/CN=localhost/emailAddress=osbuild@example.com", osbuildClientExt, "subjectAltName=DNS:localhost")
|
|
Packit Service |
509fd4 |
require.NoError(t, err)
|
|
Packit Service |
509fd4 |
defer ckp.remove()
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
testRoute(t, "https://localhost/api/composer-koji/v1/status", ckp, false)
|
|
Packit Service |
509fd4 |
})
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
t.Run("self-signed certificate", func(t *testing.T) {
|
|
Packit Service |
509fd4 |
// generate a new self-signed certificate
|
|
Packit Service |
509fd4 |
ckp, err := newSelfSignedCertificateKeyPair("/CN=osbuild.org")
|
|
Packit Service |
509fd4 |
require.NoError(t, err)
|
|
Packit Service |
509fd4 |
defer ckp.remove()
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
testRoute(t, "https://localhost/api/composer-koji/v1/status", ckp, false)
|
|
Packit Service |
509fd4 |
})
|
|
Packit Service |
509fd4 |
}
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
func testRoute(t *testing.T, route string, ckp *certificateKeyPair, expectSuccess bool) {
|
|
Packit Service |
509fd4 |
tlsConfig, err := createTLSConfig(&connectionConfig{
|
|
Packit Service |
509fd4 |
CACertFile: "/etc/osbuild-composer/ca-crt.pem",
|
|
Packit Service |
509fd4 |
ClientKeyFile: ckp.key(),
|
|
Packit Service |
509fd4 |
ClientCertFile: ckp.certificate(),
|
|
Packit Service |
509fd4 |
})
|
|
Packit Service |
509fd4 |
require.NoError(t, err)
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
transport := http.DefaultTransport.(*http.Transport).Clone()
|
|
Packit Service |
509fd4 |
transport.TLSClientConfig = tlsConfig
|
|
Packit Service |
509fd4 |
client := http.Client{Transport: transport}
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
response, err := client.Get(route)
|
|
Packit Service |
509fd4 |
if expectSuccess {
|
|
Packit Service |
509fd4 |
require.NoError(t, err)
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
var status struct {
|
|
Packit Service |
509fd4 |
Status string `json:"status"`
|
|
Packit Service |
509fd4 |
}
|
|
Packit Service |
509fd4 |
err := json.NewDecoder(response.Body).Decode(&status)
|
|
Packit Service |
509fd4 |
require.NoError(t, err)
|
|
Packit Service |
509fd4 |
|
|
Packit Service |
509fd4 |
require.Equal(t, "OK", status.Status)
|
|
Packit Service |
509fd4 |
} else {
|
|
Packit Service |
509fd4 |
require.Error(t, err)
|
|
Packit Service |
509fd4 |
}
|
|
Packit Service |
509fd4 |
}
|