Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tls_client_auth authentication mode #318

Closed
paulswartz opened this issue Dec 28, 2023 · 5 comments · Fixed by #328
Closed

tls_client_auth authentication mode #318

paulswartz opened this issue Dec 28, 2023 · 5 comments · Fixed by #328
Assignees

Comments

@paulswartz
Copy link
Collaborator

Description

Defined in RFC 8705
OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens
, this is optional for the FAPI 2.0 Message Signing profile.

See #317 and #264.

@maennchen maennchen changed the title <<"tls_client_auth">> authentication mode tls_client_auth authentication mode Jan 3, 2024
@paulswartz
Copy link
Collaborator Author

paulswartz commented Jan 7, 2024

previous text on MTLS

I think this is going to be a bit more complicated. I ran an initial test against the FAPI 2.0 Security Profile conformance tests, and ran into this failure:

Client certificate not found; the client did not supply a MTLS certification to the endpoint. In some cases this may be because the client is, incorrectly, configured to supply a TLS certificate only if the server explicitly requires a certificate at the TLS level.

OTP (at least OTP 26.1.2 and 26.2.1) is not sending a client certificate unless the server requests one with a CertificateRequest message. It's possible there's some SSL configuration which will force sending the Certificate message from the client even if it's not requested. If not, supporting this (at least for the conformance suite) will require a patch upstream.

The underlying issue isn't that Erlang/OTP doesn't send the client certificate. It's that httpc by default maintains a connection to the server, and doesn't appear to create a new connection if the ssl options change. Since we already make a request to the host (to get the Provider Configuration and JWKs), there's an open connection which didn't use the client certificate.

One option looks to be starting a new profile which doesn't use keep alives, and defaulting to for requests which include client certificates. I'm sure there are others, though!

@maennchen
Copy link
Member

@paulswartz Is there a reason why we wouldn’t set the client cert on everything? (Including the Configuration and JWKs)

@paulswartz
Copy link
Collaborator Author

That's a good point; I didn't realize that request_opts is also a parameter for oidcc_provider_configuration:load_configuration. I'll give that a shot.

@paulswartz
Copy link
Collaborator Author

This kind of works. If you don't load anything from the relevant host, everything passes.

But, if you have multiple issuers at the same hostname (as we do with the conformance suite), then accessing any provider on that host before the mTLS one causes the issue again.

@maennchen
Copy link
Member

@paulswartz Yeah, that’s not great. I’m wondering if it is a bug that httpc is reusing connections with different configurations.

In that case we’ll probably have to start net inets profiles for different tls settings or consider a different http client.

paulswartz added a commit to paulswartz/oidcc that referenced this issue Jan 8, 2024
As noted in
erlef#318 (comment),
`httpc` by default will re-use existing connections. This is great if
you're using normal HTTPS, but if you're using client authentication
then you need to make sure that every time `httpc` connects to a host,
it's using the client authentication, which is impossible in practice.

This works around that, by creating a new profile which disables that
functionality. Using that profile for requests which provide SSL
overrides will ensure that each of those requests will use the client certificate.
paulswartz added a commit to paulswartz/oidcc that referenced this issue Jan 8, 2024
As noted in
erlef#318 (comment),
`httpc` by default will re-use existing connections. This is great if
you're using normal HTTPS, but if you're using client authentication
then you need to make sure that every time `httpc` connects to a host,
it's using the client authentication, which is impossible in practice.

This works around that, by creating a new profile which disables that
functionality. Using that profile for requests which provide SSL
overrides will ensure that each of those requests will use the client certificate.
paulswartz added a commit to paulswartz/oidcc that referenced this issue Jan 8, 2024
As noted in
erlef#318 (comment),
`httpc` by default will re-use existing connections. This is great if
you're using normal HTTPS, but if you're using client authentication
then you need to make sure that every time `httpc` connects to a host,
it's using the client authentication, which is impossible in practice.

This works around that, by creating a new profile which disables that
functionality. Using that profile for requests which provide SSL
overrides will ensure that each of those requests will use the client certificate.
maennchen pushed a commit that referenced this issue Jan 10, 2024
* feat: parse `mtls_endpoint_aliases`

* feat: use `mtls_endpoint_aliases` if using `tls_client_auth` method

* feat(oidcc_profile): allow tls_client_auth, enforce ciphers

* feat: create an httpc profile which disables keep-alive/pipelining

As noted in
#318 (comment),
`httpc` by default will re-use existing connections. This is great if
you're using normal HTTPS, but if you're using client authentication
then you need to make sure that every time `httpc` connects to a host,
it's using the client authentication, which is impossible in practice.

This works around that, by creating a new profile which disables that
functionality. Using that profile for requests which provide SSL
overrides will ensure that each of those requests will use the client certificate.

* feat: tell `httpc` to close the connection if we're using client certs

In addition to the separate profile, this header serves as a note to
both the remote server and `httpc` that we're not keeping the connection
open after the request.`

* feat: `httpc_profile` opt and have the client manage the HTTPC profile

* fixup! feat: `httpc_profile` opt and have the client manage the HTTPC profile
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants