Skip to content

Commit 3d8a165

Browse files
e2e: fix Dex token TLS verification for test CA and CI
Sign leaves with the parsed CA so AuthorityKeyId matches SubjectKeyId on ca.pem. Add host.docker.internal to Dex/API SANs, set tls.ServerName to the Dex Docker hostname when posting to dex/token, and fail if ca.pem does not parse into the root pool.
1 parent bdbc262 commit 3d8a165

4 files changed

Lines changed: 34 additions & 10 deletions

File tree

test/e2e/helpers.go

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,21 +39,36 @@ func prepareConfigsAndCerts(t *testing.T, e e2e.Environment) {
3939
testtls.GenerateCerts(
4040
filepath.Join(e.SharedDir(), certsSharedDir),
4141
getContainerName(e, "observatorium-api"),
42-
[]string{getContainerName(e, "observatorium-api"), "127.0.0.1"},
42+
[]string{
43+
getContainerName(e, "observatorium-api"),
44+
"127.0.0.1",
45+
"host.docker.internal",
46+
},
4347
getContainerName(e, "dex"),
44-
[]string{getContainerName(e, "dex"), "127.0.0.1"},
48+
[]string{
49+
getContainerName(e, "dex"),
50+
"127.0.0.1",
51+
"host.docker.internal",
52+
},
4553
),
4654
)
4755

4856
testutil.Ok(t, exec.Command("cp", "-r", "../config", filepath.Join(e.SharedDir(), configSharedDir)).Run())
4957
}
5058

5159
// obtainToken obtains a bearer token needed for communication with the API.
52-
func obtainToken(endpoint string, tlsConf *tls.Config) (string, error) {
60+
// dexTLSHost is the Dex DNS name from the test CA (e.g. {network}-dex); set it so TLS verifies the
61+
// server cert when the TCP dial target is 127.0.0.1 or host.docker.internal (e2e.Endpoint).
62+
func obtainToken(endpoint, dexTLSHost string, tlsConf *tls.Config) (string, error) {
5363
type token struct {
5464
IDToken string `json:"id_token"`
5565
}
5666

67+
tlsClient := tlsConf.Clone()
68+
if dexTLSHost != "" {
69+
tlsClient.ServerName = dexTLSHost
70+
}
71+
5772
data := url.Values{}
5873
data.Add("grant_type", "password")
5974
data.Add("username", "admin@example.com")
@@ -70,7 +85,7 @@ func obtainToken(endpoint string, tlsConf *tls.Config) (string, error) {
7085

7186
c := &http.Client{
7287
Transport: &http.Transport{
73-
TLSClientConfig: tlsConf,
88+
TLSClientConfig: tlsClient,
7489
},
7590
}
7691

@@ -104,7 +119,9 @@ func getTLSClientConfig(t *testing.T, e e2e.Environment) *tls.Config {
104119
testutil.Ok(t, err)
105120

106121
cp := x509.NewCertPool()
107-
cp.AppendCertsFromPEM(cert)
122+
if ok := cp.AppendCertsFromPEM(cert); !ok {
123+
t.Fatal("failed to parse CA certificate from ca.pem")
124+
}
108125

109126
return &tls.Config{
110127
RootCAs: cp,

test/e2e/services.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ func startBaseServices(t *testing.T, e e2e.Environment) (
191191

192192
createTenantsYAML(t, e, dex.InternalEndpoint("https"), opa.InternalEndpoint("http"), getContainerName(e, "observatorium-api"))
193193

194-
token, err := obtainToken(dex.Endpoint("https"), getTLSClientConfig(t, e))
194+
token, err := obtainToken(dex.Endpoint("https"), getContainerName(e, "dex"), getTLSClientConfig(t, e))
195195
testutil.Ok(t, err)
196196

197197
return dex, token, gubernator.InternalEndpoint("grpc")

test/e2e/tenants_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func TestTenantsRetryAuthenticationProviderRegistration(t *testing.T) {
5959

6060
// Restart Dex.
6161
testutil.Ok(t, e2e.StartAndWaitReady(dex))
62-
token, err := obtainToken(dex.Endpoint("https"), getTLSClientConfig(t, e))
62+
token, err := obtainToken(dex.Endpoint("https"), getContainerName(e, "dex"), getTLSClientConfig(t, e))
6363
testutil.Ok(t, err)
6464

6565
up, err := newUpRun(

test/testtls/generate.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ func GenerateCerts(
6565
return err
6666
}
6767

68+
// Use the parsed CA for signing leaves so leaf AuthorityKeyId matches the issued CA's
69+
// SubjectKeyId (the in-memory template may omit fields the encoder adds).
70+
caParsed, err := x509.ParseCertificate(caBytes)
71+
if err != nil {
72+
return fmt.Errorf("parse CA certificate: %w", err)
73+
}
74+
6875
caPEM := new(bytes.Buffer)
6976
if err := pem.Encode(caPEM, &pem.Block{
7077
Type: "CERTIFICATE",
@@ -88,15 +95,15 @@ func GenerateCerts(
8895
key: caPrivKeyPEM.Bytes(),
8996
}
9097

91-
apiBundle, err := generateCert(ca, caPrivKey, false, apiCommonName, apiSANs, nil)
98+
apiBundle, err := generateCert(caParsed, caPrivKey, false, apiCommonName, apiSANs, nil)
9299
if err != nil {
93100
return err
94101
}
95-
dexBundle, err := generateCert(ca, caPrivKey, false, dexCommonName, dexSANs, nil)
102+
dexBundle, err := generateCert(caParsed, caPrivKey, false, dexCommonName, dexSANs, nil)
96103
if err != nil {
97104
return err
98105
}
99-
clientBundle, err := generateCert(ca, caPrivKey, true, clientCommonName, []string{clientSANs}, []string{clientGroups})
106+
clientBundle, err := generateCert(caParsed, caPrivKey, true, clientCommonName, []string{clientSANs}, []string{clientGroups})
100107
if err != nil {
101108
return err
102109
}

0 commit comments

Comments
 (0)