Skip to content

Commit 99c099f

Browse files
committed
feat: backchannel logout request client tls configuration
1 parent 924be24 commit 99c099f

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
@@ -33,6 +33,7 @@ require (
3333
github.com/gorilla/sessions v1.2.0
3434
github.com/gtank/cryptopasta v0.0.0-20170601214702-1f550f6f2f69
3535
github.com/hashicorp/go-cleanhttp v0.5.2
36+
github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1
3637
github.com/jackc/pgx/v4 v4.13.0
3738
github.com/jmoiron/sqlx v1.3.4
3839
github.com/julienschmidt/httprouter v1.3.0

go.sum

+8
Original file line numberDiff line numberDiff line change
@@ -952,8 +952,15 @@ github.com/hashicorp/go-retryablehttp v0.7.0 h1:eu1EI/mbirUgP5C8hVsTNaGZreBDlYiw
952952
github.com/hashicorp/go-retryablehttp v0.7.0/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
953953
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
954954
github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
955+
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1 h1:78ki3QBevHwYrVxnyVeaEz+7WtifHhauYF23es/0KlI=
956+
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8=
957+
github.com/hashicorp/go-secure-stdlib/strutil v0.1.1 h1:nd0HIW15E6FG1MsnArYaHfuw9C2zgzM8LxkG5Ty/788=
958+
github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U=
959+
github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1 h1:Yc026VyMyIpq1UWRnakHRG01U8fJm+nEfEmjoAb00n8=
960+
github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1/go.mod h1:l8slYwnJA26yBz+ErHpp2IRCLr0vuOMGBORIz4rRiAs=
955961
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
956962
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
963+
github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc=
957964
github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A=
958965
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
959966
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
@@ -1576,6 +1583,7 @@ github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfF
15761583
github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk=
15771584
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
15781585
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
1586+
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
15791587
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
15801588
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
15811589
github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig=

spec/config.json

+55
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,61 @@
447447
}
448448
}
449449
},
450+
"client.tls": {
451+
"type": "object",
452+
"additionalProperties": false,
453+
"description": "Configures http client TLS settings.",
454+
"properties": {
455+
"min_version": {
456+
"type": "string",
457+
"description": "Minimum supported TLS version.",
458+
"examples": [
459+
"tls10","tls11","tls12","tls13"
460+
]
461+
},
462+
"max_version": {
463+
"type": "string",
464+
"description": "Maximum supported TLS version.",
465+
"examples": [
466+
"tls10","tls11","tls12","tls13"
467+
]
468+
},
469+
"cipher_suites": {
470+
"type": "array",
471+
"description": "A list of supported cipher suites.",
472+
"items": {
473+
"type": "string"
474+
},
475+
"examples": [
476+
"TLS_RSA_WITH_RC4_128_SHA",
477+
"TLS_RSA_WITH_3DES_EDE_CBC_SHA",
478+
"TLS_RSA_WITH_AES_128_CBC_SHA",
479+
"TLS_RSA_WITH_AES_256_CBC_SHA",
480+
"TLS_RSA_WITH_AES_128_CBC_SHA256",
481+
"TLS_RSA_WITH_AES_128_GCM_SHA256",
482+
"TLS_RSA_WITH_AES_256_GCM_SHA384",
483+
"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
484+
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
485+
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
486+
"TLS_ECDHE_RSA_WITH_RC4_128_SHA",
487+
"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
488+
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
489+
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
490+
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
491+
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
492+
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
493+
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
494+
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
495+
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
496+
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
497+
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
498+
"TLS_AES_128_GCM_SHA256",
499+
"TLS_AES_256_GCM_SHA384",
500+
"TLS_CHACHA20_POLY1305_SHA256"
501+
]
502+
}
503+
}
504+
},
450505
"dsn": {
451506
"type": "string",
452507
"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)