Skip to content

Commit

Permalink
feat: back-channel logout request client tls configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
aarmam committed Nov 2, 2022
1 parent 70e6fe9 commit f60fcad
Show file tree
Hide file tree
Showing 6 changed files with 297 additions and 9 deletions.
25 changes: 20 additions & 5 deletions consent/strategy_default.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import (
"strings"
"time"

"github.com/ory/x/httpx"

"github.com/ory/hydra/driver/config"

"github.com/ory/x/errorsx"
Expand Down Expand Up @@ -60,17 +62,30 @@ const (
)

type DefaultStrategy struct {
c *config.DefaultProvider
r InternalRegistry
c *config.DefaultProvider
r InternalRegistry
httpClientOptions httpx.ResilientOptions
}

func NewStrategy(
r InternalRegistry,
c *config.DefaultProvider,
) *DefaultStrategy {
httpClientTlsConfig, err := c.TLSClientConfigWithDefaultFallback(config.KeyPrefixClientBackChannelLogout)
if err != nil {
r.Logger().WithError(err).Fatalf("Unable to setup back-channel logout http client TLS configuration.")
}
httpClientOptions := httpx.ResilientClientWithClient(&http.Client{
Timeout: time.Minute,
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
TLSClientConfig: httpClientTlsConfig,
},
})
return &DefaultStrategy{
c: c,
r: r,
c: c,
r: r,
httpClientOptions: httpClientOptions,
}
}

Expand Down Expand Up @@ -674,7 +689,7 @@ func (s *DefaultStrategy) executeBackChannelLogout(ctx context.Context, r *http.
WithField("client_id", t.clientID).
WithField("backchannel_logout_url", t.url)

res, err := s.r.HTTPClient(ctx).PostForm(t.url, url.Values{"logout_token": {t.token}})
res, err := s.r.HTTPClient(ctx, s.httpClientOptions).PostForm(t.url, url.Values{"logout_token": {t.token}})
if err != nil {
log.WithError(err).Error("Unable to execute OpenID Connect Back-Channel Logout Request")
return
Expand Down
70 changes: 70 additions & 0 deletions driver/config/tls.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ package config
import (
"context"
"crypto/tls"
"fmt"
"strings"

"github.com/hashicorp/go-secure-stdlib/tlsutil"
"github.com/pkg/errors"

"github.com/ory/x/logrusx"
Expand All @@ -24,6 +27,35 @@ const (
KeyTLSCertPath = "serve." + KeySuffixTLSCertPath
KeyTLSKeyPath = "serve." + KeySuffixTLSKeyPath
KeyTLSEnabled = "serve." + KeySuffixTLSEnabled

KeyClientTLSInsecureSkipVerify = "tls.insecure_skip_verify"
KeySuffixClientTLSCipherSuites = "tls.cipher_suites"
KeySuffixClientTLSMinVer = "tls.min_version"
KeySuffixClientTLSMaxVer = "tls.max_version"
)

type ClientInterface interface {
Key(suffix string) string
}

func (iface *clientPrefix) Key(suffix string) string {
return fmt.Sprintf("%s.%s", iface.prefix, suffix)
}

type clientPrefix struct {
prefix string
}

var (
KeyPrefixClientDefault ClientInterface = &clientPrefix{
prefix: "client.default",
}
KeyPrefixClientBackChannelLogout ClientInterface = &clientPrefix{
prefix: "client.back_channel_logout",
}
KeyPrefixClientRefreshTokenHook ClientInterface = &clientPrefix{
prefix: "client.refresh_token_hook",
}
)

type TLSConfig interface {
Expand Down Expand Up @@ -63,6 +95,44 @@ func (p *DefaultProvider) TLS(ctx context.Context, iface ServeInterface) TLSConf
}
}

func (p *DefaultProvider) TLSClientConfigDefault() (*tls.Config, error) {
return p.TLSClientConfigWithDefaultFallback(KeyPrefixClientDefault)
}

func (p *DefaultProvider) TLSClientConfigWithDefaultFallback(iface ClientInterface) (*tls.Config, error) {
tlsClientConfig := new(tls.Config)
tlsClientConfig.InsecureSkipVerify = p.p.BoolF(KeyClientTLSInsecureSkipVerify, false)

if p.p.Exists(KeyPrefixClientDefault.Key(KeySuffixClientTLSCipherSuites)) || p.p.Exists(iface.Key(KeySuffixClientTLSCipherSuites)) {
keyCipherSuites := p.p.StringsF(iface.Key(KeySuffixClientTLSCipherSuites), p.p.Strings(KeyPrefixClientDefault.Key(KeySuffixClientTLSCipherSuites)))
cipherSuites, err := tlsutil.ParseCiphers(strings.Join(keyCipherSuites[:], ","))
if err != nil {
return nil, errors.WithMessage(err, "Unable to setup client TLS configuration")
}
tlsClientConfig.CipherSuites = cipherSuites
}

if p.p.Exists(KeyPrefixClientDefault.Key(KeySuffixClientTLSMinVer)) || p.p.Exists(iface.Key(KeySuffixClientTLSMinVer)) {
keyMinVer := p.p.StringF(iface.Key(KeySuffixClientTLSMinVer), p.p.String(KeyPrefixClientDefault.Key(KeySuffixClientTLSMinVer)))
if tlsMinVer, found := tlsutil.TLSLookup[keyMinVer]; !found {
return nil, errors.Errorf("Unable to setup client TLS configuration. Invalid minimum TLS version: %s", keyMinVer)
} else {
tlsClientConfig.MinVersion = tlsMinVer
}
}

if p.p.Exists(KeyPrefixClientDefault.Key(KeySuffixClientTLSMaxVer)) || p.p.Exists(iface.Key(KeySuffixClientTLSMaxVer)) {
keyMaxVer := p.p.StringF(iface.Key(KeySuffixClientTLSMaxVer), p.p.String(KeyPrefixClientDefault.Key(KeySuffixClientTLSMaxVer)))
if tlsMaxVer, found := tlsutil.TLSLookup[keyMaxVer]; !found {
return nil, errors.Errorf("Unable to setup client TLS configuration. Invalid maximum TLS version: %s", keyMaxVer)
} else {
tlsClientConfig.MaxVersion = tlsMaxVer
}
}

return tlsClientConfig, nil
}

func (c *tlsConfig) GetCertificateFunc(stopReload <-chan struct{}, log *logrusx.Logger) (func(*tls.ClientHelloInfo) (*tls.Certificate, error), error) {
if c.certPath != "" && c.keyPath != "" { // attempt to load from disk first (enables hot-reloading)
ctx, cancel := context.WithCancel(context.Background())
Expand Down
87 changes: 87 additions & 0 deletions driver/config/tls_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package config

import (
"context"
"crypto/tls"
"testing"

"github.com/stretchr/testify/assert"

"github.com/ory/x/configx"
"github.com/ory/x/logrusx"
)

func TestTLSClientConfig_CipherSuite(t *testing.T) {
l := logrusx.New("", "")
c := MustNew(context.TODO(), l, configx.WithValue("client.default.tls.cipher_suites", []string{"TLS_AES_128_GCM_SHA256", "TLS_AES_256_GCM_SHA384"}))

tlsClientConfig, err := c.TLSClientConfigDefault()
assert.NoError(t, err)
cipherSuites := tlsClientConfig.CipherSuites

assert.Len(t, cipherSuites, 2)
assert.Equal(t, tls.TLS_AES_128_GCM_SHA256, cipherSuites[0])
assert.Equal(t, tls.TLS_AES_256_GCM_SHA384, cipherSuites[1])
}

func TestTLSClientConfig_InvalidCipherSuite(t *testing.T) {
l := logrusx.New("", "")
c := MustNew(context.TODO(), l, configx.WithValue("client.default.tls.cipher_suites", []string{"TLS_AES_128_GCM_SHA256", "TLS_INVALID_CIPHER_SUITE"}))

_, err := c.TLSClientConfigDefault()

assert.EqualError(t, err, "Unable to setup client TLS configuration: unsupported cipher \"TLS_INVALID_CIPHER_SUITE\"")
}

func TestTLSClientConfig_MinVersion(t *testing.T) {
l := logrusx.New("", "")
c := MustNew(context.TODO(), l, configx.WithValue("client.default.tls.min_version", "tls13"))

tlsClientConfig, err := c.TLSClientConfigDefault()

assert.NoError(t, err)
assert.Equal(t, uint16(tls.VersionTLS13), tlsClientConfig.MinVersion)
}

func TestTLSClientConfig_InvalidMinVersion(t *testing.T) {
l := logrusx.New("", "")
c := MustNew(context.TODO(), l, configx.WithValue("client.default.tls.min_version", "tlsx"))

_, err := c.TLSClientConfigDefault()

assert.EqualError(t, err, "Unable to setup client TLS configuration. Invalid minimum TLS version: tlsx")
}

func TestTLSClientConfig_MaxVersion(t *testing.T) {
l := logrusx.New("", "")
c := MustNew(context.TODO(), l, configx.WithValue("client.default.tls.max_version", "tls10"))

tlsClientConfig, err := c.TLSClientConfigDefault()

assert.NoError(t, err)
assert.Equal(t, uint16(tls.VersionTLS10), tlsClientConfig.MaxVersion)
}

func TestTLSClientConfig_InvalidMaxTlsVersion(t *testing.T) {
l := logrusx.New("", "")
c := MustNew(context.TODO(), l, configx.WithValue("client.default.tls.max_version", "tlsx"))

_, err := c.TLSClientConfigDefault()

assert.EqualError(t, err, "Unable to setup client TLS configuration. Invalid maximum TLS version: tlsx")
}

func TestTLSClientConfig_WithDefaultFallback(t *testing.T) {
l := logrusx.New("", "")
c := MustNew(context.TODO(), l)
ctx := context.Background()
c.MustSet(ctx, "client.default.tls.min_version", "tls11")
c.MustSet(ctx, "client.default.tls.max_version", "tls12")
c.MustSet(ctx, "client.back_channel_logout.tls.max_version", "tls13")

tlsClientConfig, err := c.TLSClientConfigWithDefaultFallback(KeyPrefixClientBackChannelLogout)

assert.NoError(t, err)
assert.Equal(t, uint16(tls.VersionTLS11), tlsClientConfig.MinVersion)
assert.Equal(t, uint16(tls.VersionTLS13), tlsClientConfig.MaxVersion)
}
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ require (
github.com/gorilla/sessions v1.2.1
github.com/gtank/cryptopasta v0.0.0-20170601214702-1f550f6f2f69
github.com/hashicorp/go-retryablehttp v0.7.1
github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1
github.com/instana/testify v1.6.2-0.20200721153833-94b1851f4d65
github.com/jackc/pgx/v4 v4.16.1
github.com/jmoiron/sqlx v1.3.5
Expand Down Expand Up @@ -147,6 +148,9 @@ require (
github.com/gorilla/handlers v1.5.1 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.2 // indirect
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1 // indirect
github.com/hashicorp/go-secure-stdlib/strutil v0.1.1 // indirect
github.com/hashicorp/go-sockaddr v1.0.2 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/huandu/xstrings v1.3.2 // indirect
github.com/imdario/mergo v0.3.12 // indirect
Expand Down Expand Up @@ -206,6 +210,7 @@ require (
github.com/prometheus/common v0.32.1 // indirect
github.com/prometheus/procfs v0.6.0 // indirect
github.com/rogpeppe/go-internal v1.9.0 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
github.com/santhosh-tekuri/jsonschema v1.2.4 // indirect
github.com/seatgeek/logrus-gelf-formatter v0.0.0-20210414080842-5b05eb8ff761 // indirect
github.com/segmentio/backo-go v0.0.0-20200129164019-23eae7c10bd3 // indirect
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -827,8 +827,15 @@ github.com/hashicorp/go-retryablehttp v0.7.1 h1:sUiuQAnLlbvmExtFQs72iFW/HXeUn8Z1
github.com/hashicorp/go-retryablehttp v0.7.1/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1 h1:78ki3QBevHwYrVxnyVeaEz+7WtifHhauYF23es/0KlI=
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8=
github.com/hashicorp/go-secure-stdlib/strutil v0.1.1 h1:nd0HIW15E6FG1MsnArYaHfuw9C2zgzM8LxkG5Ty/788=
github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U=
github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1 h1:Yc026VyMyIpq1UWRnakHRG01U8fJm+nEfEmjoAb00n8=
github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1/go.mod h1:l8slYwnJA26yBz+ErHpp2IRCLr0vuOMGBORIz4rRiAs=
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc=
github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
Expand Down Expand Up @@ -1377,6 +1384,7 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
github.com/santhosh-tekuri/jsonschema v1.2.4 h1:hNhW8e7t+H1vgY+1QeEQpveR6D4+OwKPXCfD2aieJis=
Expand Down
Loading

0 comments on commit f60fcad

Please sign in to comment.