Skip to content

Commit b80598c

Browse files
committed
feat: backchannel logout request client tls configuration
1 parent 21b470d commit b80598c

File tree

6 files changed

+195
-9
lines changed

6 files changed

+195
-9
lines changed

consent/strategy_default.go

+19-9
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ package consent
2222

2323
import (
2424
"context"
25+
"crypto/tls"
2526
"net/http"
2627
"net/url"
2728
"strconv"
@@ -67,17 +68,20 @@ const (
6768
)
6869

6970
type DefaultStrategy struct {
70-
c *config.Provider
71-
r InternalRegistry
71+
c *config.Provider
72+
r InternalRegistry
73+
tlsClientConfig *tls.Config
7274
}
7375

74-
func NewStrategy(
75-
r InternalRegistry,
76-
c *config.Provider,
77-
) *DefaultStrategy {
76+
func NewStrategy(r InternalRegistry, c *config.Provider) *DefaultStrategy {
77+
clientConfig, err := c.TLSClientConfig()
78+
if err != nil {
79+
r.Logger().WithError(err).Fatalf("Unable to setup backchannel logout request client TLS configuration.")
80+
}
7881
return &DefaultStrategy{
79-
c: c,
80-
r: r,
82+
c: c,
83+
r: r,
84+
tlsClientConfig: clientConfig,
8185
}
8286
}
8387

@@ -697,7 +701,13 @@ func (s *DefaultStrategy) executeBackChannelLogout(ctx context.Context, r *http.
697701
}
698702

699703
var wg sync.WaitGroup
700-
hc := httpx.NewResilientClient()
704+
hc := httpx.NewResilientClient(
705+
httpx.ResilientClientWithClient(&http.Client{
706+
Timeout: time.Minute,
707+
Transport: &http.Transport{
708+
TLSClientConfig: s.tlsClientConfig,
709+
},
710+
}))
701711
wg.Add(len(tasks))
702712

703713
var execute = func(t task) {

driver/config/tls.go

+41
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ package config
22

33
import (
44
"crypto/tls"
5+
"strings"
6+
7+
"github.com/hashicorp/go-secure-stdlib/tlsutil"
8+
"github.com/pkg/errors"
59

610
"github.com/ory/x/tlsx"
711
)
@@ -19,6 +23,10 @@ const (
1923
KeyTLSKeyString = "serve." + KeySuffixTLSKeyString
2024
KeyTLSCertPath = "serve." + KeySuffixTLSCertPath
2125
KeyTLSKeyPath = "serve." + KeySuffixTLSKeyPath
26+
27+
KeyClientTLSCipherSuites = "client.tls.cipher_suites"
28+
KeyClientTLSMinVer = "client.tls.min_version"
29+
KeyClientTLSMaxVer = "client.tls.max_version"
2230
)
2331

2432
type TLSConfig interface {
@@ -47,6 +55,39 @@ func (p *Provider) TLS(iface ServeInterface) TLSConfig {
4755
}
4856
}
4957

58+
func (p *Provider) TLSClientConfig() (*tls.Config, error) {
59+
tlsClientConfig := new(tls.Config)
60+
61+
if p.p.Exists(KeyClientTLSCipherSuites) {
62+
keyCipherSuites := p.p.Strings(KeyClientTLSCipherSuites)
63+
cipherSuites, err := tlsutil.ParseCiphers(strings.Join(keyCipherSuites[:], ","))
64+
if err != nil {
65+
return nil, errors.WithMessage(err, "Unable to setup client TLS configuration")
66+
}
67+
tlsClientConfig.CipherSuites = cipherSuites
68+
}
69+
70+
if p.p.Exists(KeyClientTLSMinVer) {
71+
keyMinVer := p.p.String(KeyClientTLSMinVer)
72+
if tlsMinVer, found := tlsutil.TLSLookup[keyMinVer]; !found {
73+
return nil, errors.Errorf("Unable to setup client TLS configuration. Invalid minimum TLS version: %s", keyMinVer)
74+
} else {
75+
tlsClientConfig.MinVersion = tlsMinVer
76+
}
77+
}
78+
79+
if p.p.Exists(KeyClientTLSMaxVer) {
80+
keyMaxVer := p.p.String(KeyClientTLSMaxVer)
81+
if tlsMaxVer, found := tlsutil.TLSLookup[keyMaxVer]; !found {
82+
return nil, errors.Errorf("Unable to setup client TLS configuration. Invalid maximum TLS version: %s", keyMaxVer)
83+
} else {
84+
tlsClientConfig.MaxVersion = tlsMaxVer
85+
}
86+
}
87+
88+
return tlsClientConfig, nil
89+
}
90+
5091
type tlsConfig struct {
5192
enabled bool
5293
allowTerminationFrom []string

driver/config/tls_test.go

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package config
2+
3+
import (
4+
"crypto/tls"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
9+
"github.com/ory/x/configx"
10+
"github.com/ory/x/logrusx"
11+
)
12+
13+
func TestTLSClientConfig_CipherSuite(t *testing.T) {
14+
l := logrusx.New("", "")
15+
c := MustNew(l, configx.WithValue("client.tls.cipher_suites", []string{"TLS_AES_128_GCM_SHA256", "TLS_AES_256_GCM_SHA384"}))
16+
17+
tlsClientConfig, err := c.TLSClientConfig()
18+
assert.NoError(t, err)
19+
cipherSuites := tlsClientConfig.CipherSuites
20+
21+
assert.Len(t, cipherSuites, 2)
22+
assert.Equal(t, tls.TLS_AES_128_GCM_SHA256, cipherSuites[0])
23+
assert.Equal(t, tls.TLS_AES_256_GCM_SHA384, cipherSuites[1])
24+
}
25+
26+
func TestTLSClientConfig_InvalidCipherSuite(t *testing.T) {
27+
l := logrusx.New("", "")
28+
c := MustNew(l, configx.WithValue("client.tls.cipher_suites", []string{"TLS_AES_128_GCM_SHA256", "TLS_INVALID_CIPHER_SUITE"}))
29+
30+
_, err := c.TLSClientConfig()
31+
32+
assert.EqualError(t, err, "Unable to setup client TLS configuration: unsupported cipher \"TLS_INVALID_CIPHER_SUITE\"")
33+
}
34+
35+
func TestTLSClientConfig_MinVersion(t *testing.T) {
36+
l := logrusx.New("", "")
37+
c := MustNew(l, configx.WithValue("client.tls.min_version", "tls13"))
38+
39+
tlsClientConfig, err := c.TLSClientConfig()
40+
41+
assert.NoError(t, err)
42+
assert.Equal(t, uint16(tls.VersionTLS13), tlsClientConfig.MinVersion)
43+
}
44+
45+
func TestTLSClientConfig_InvalidMinVersion(t *testing.T) {
46+
l := logrusx.New("", "")
47+
c := MustNew(l, configx.WithValue("client.tls.min_version", "tlsx"))
48+
49+
_, err := c.TLSClientConfig()
50+
51+
assert.EqualError(t, err, "Unable to setup client TLS configuration. Invalid minimum TLS version: tlsx")
52+
}
53+
54+
func TestTLSClientConfig_MaxVersion(t *testing.T) {
55+
l := logrusx.New("", "")
56+
c := MustNew(l, configx.WithValue("client.tls.max_version", "tls10"))
57+
58+
tlsClientConfig, err := c.TLSClientConfig()
59+
60+
assert.NoError(t, err)
61+
assert.Equal(t, uint16(tls.VersionTLS10), tlsClientConfig.MaxVersion)
62+
}
63+
64+
func TestTLSClientConfig_InvalidMaxTlsVersion(t *testing.T) {
65+
l := logrusx.New("", "")
66+
c := MustNew(l, configx.WithValue("client.tls.max_version", "tlsx"))
67+
68+
_, err := c.TLSClientConfig()
69+
70+
assert.EqualError(t, err, "Unable to setup client TLS configuration. Invalid maximum TLS version: tlsx")
71+
}

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ require (
3232
github.com/gorilla/sessions v1.2.0
3333
github.com/gtank/cryptopasta v0.0.0-20170601214702-1f550f6f2f69
3434
github.com/hashicorp/go-cleanhttp v0.5.2
35+
github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1
3536
github.com/jackc/pgx/v4 v4.13.0
3637
github.com/jmoiron/sqlx v1.3.4
3738
github.com/julienschmidt/httprouter v1.3.0

go.sum

+8
Original file line numberDiff line numberDiff line change
@@ -899,7 +899,14 @@ github.com/hashicorp/go-retryablehttp v0.7.0 h1:eu1EI/mbirUgP5C8hVsTNaGZreBDlYiw
899899
github.com/hashicorp/go-retryablehttp v0.7.0/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
900900
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
901901
github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
902+
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1 h1:78ki3QBevHwYrVxnyVeaEz+7WtifHhauYF23es/0KlI=
903+
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8=
904+
github.com/hashicorp/go-secure-stdlib/strutil v0.1.1 h1:nd0HIW15E6FG1MsnArYaHfuw9C2zgzM8LxkG5Ty/788=
905+
github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U=
906+
github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1 h1:Yc026VyMyIpq1UWRnakHRG01U8fJm+nEfEmjoAb00n8=
907+
github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1/go.mod h1:l8slYwnJA26yBz+ErHpp2IRCLr0vuOMGBORIz4rRiAs=
902908
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
909+
github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc=
903910
github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A=
904911
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
905912
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
@@ -1497,6 +1504,7 @@ github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfF
14971504
github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk=
14981505
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
14991506
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
1507+
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
15001508
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
15011509
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
15021510
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=

spec/config.json

+55
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,61 @@
421421
}
422422
}
423423
},
424+
"client.tls": {
425+
"type": "object",
426+
"additionalProperties": false,
427+
"description": "Configures http client TLS settings.",
428+
"properties": {
429+
"min_version": {
430+
"type": "string",
431+
"description": "Minimum supported TLS version.",
432+
"examples": [
433+
"tls10","tls11","tls12","tls13"
434+
]
435+
},
436+
"max_version": {
437+
"type": "string",
438+
"description": "Maximum supported TLS version.",
439+
"examples": [
440+
"tls10","tls11","tls12","tls13"
441+
]
442+
},
443+
"cipher_suites": {
444+
"type": "array",
445+
"description": "A list of supported cipher suites.",
446+
"items": {
447+
"type": "string"
448+
},
449+
"examples": [
450+
"TLS_RSA_WITH_RC4_128_SHA",
451+
"TLS_RSA_WITH_3DES_EDE_CBC_SHA",
452+
"TLS_RSA_WITH_AES_128_CBC_SHA",
453+
"TLS_RSA_WITH_AES_256_CBC_SHA",
454+
"TLS_RSA_WITH_AES_128_CBC_SHA256",
455+
"TLS_RSA_WITH_AES_128_GCM_SHA256",
456+
"TLS_RSA_WITH_AES_256_GCM_SHA384",
457+
"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
458+
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
459+
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
460+
"TLS_ECDHE_RSA_WITH_RC4_128_SHA",
461+
"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
462+
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
463+
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
464+
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
465+
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
466+
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
467+
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
468+
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
469+
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
470+
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
471+
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
472+
"TLS_AES_128_GCM_SHA256",
473+
"TLS_AES_256_GCM_SHA384",
474+
"TLS_CHACHA20_POLY1305_SHA256"
475+
]
476+
}
477+
}
478+
},
424479
"dsn": {
425480
"type": "string",
426481
"description": "Sets the data source name. This configures the backend where ORY Hydra persists data. If dsn is \"memory\", data will be written to memory and is lost when you restart this instance. ORY Hydra supports popular SQL databases. For more detailed configuration information go to: https://www.ory.sh/docs/hydra/dependencies-environment#sql"

0 commit comments

Comments
 (0)