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

Improve certificate authentication #93

Merged
merged 25 commits into from
Apr 11, 2021

Conversation

Firgeis
Copy link
Contributor

@Firgeis Firgeis commented Apr 7, 2021

This PR improves client certificate handling in piaf with the following:

  • Allows to check server certificate validity (either from a file or from a certificate string)
  • Allows to present a client certificate for authentication (from a certificate string and private key string)

Outstanding issues:

@Firgeis Firgeis changed the title Improve certificate authetication Improve certificate authentication Apr 7, 2021
@anmonteiro
Copy link
Owner

Whoa! I really like this. Thanks for putting in the work.

Give me some time to review it.

What are some blockers for you right now?

@Firgeis
Copy link
Contributor Author

Firgeis commented Apr 7, 2021

Well mostly getting the changes to ocaml-ssl in and updating the dependency

@Firgeis
Copy link
Contributor Author

Firgeis commented Apr 10, 2021

These commits fix the outstanding test issues

@anmonteiro
Copy link
Owner

Thanks, I'm gonna take a look at this soon. I pushed a commit bumping the Nix package sources to a commit that includes your openssl PR.

Let's see what CI says.

@Firgeis Firgeis marked this pull request as ready for review April 10, 2021 06:13
Copy link
Owner

@anmonteiro anmonteiro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great!

I left a couple comments that are mostly nits, some questions, and a couple code suggestions. Let me know what you think.

bin/carl.ml Show resolved Hide resolved
lib/cert.ml Outdated Show resolved Hide resolved
lib/cert.ml Outdated Show resolved Hide resolved
lib/openssl.ml Outdated Show resolved Hide resolved
lib/openssl.ml Outdated Show resolved Hide resolved
lib/openssl.ml Outdated Show resolved Hide resolved
lib_test/helper_server.ml Outdated Show resolved Hide resolved
lib_test/test_client.ml Show resolved Hide resolved
@Firgeis Firgeis requested a review from anmonteiro April 10, 2021 20:03
Copy link
Owner

@anmonteiro anmonteiro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, 2nd round! Everything looks great, there's only the change in bin/carl.ml that I'd rather revert.

bin/carl.ml Outdated Show resolved Hide resolved
lib/cert.ml Show resolved Hide resolved
@Firgeis
Copy link
Contributor Author

Firgeis commented Apr 11, 2021

I have added the possibility of passing the cert/key pair as files, and added to carl an implementation resembling curl of client certificates

@Firgeis Firgeis requested a review from anmonteiro April 11, 2021 20:05
@anmonteiro anmonteiro merged commit 6e1b433 into anmonteiro:master Apr 11, 2021
@anmonteiro
Copy link
Owner

Thank you!

let cert = "./certificates/server.pem" in
let priv_key = "./certificates/server.key" in
Lwt_io.establish_server_with_client_socket
listen_address
(fun client_addr fd ->
let server_ctx = Ssl.create_context Ssl.TLSv1_3 Ssl.Server_context in
Ssl.disable_protocols server_ctx [ Ssl.SSLv23; Ssl.TLSv1_1 ];
Ssl.load_verify_locations server_ctx ca "";
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Firgeis why did you add this here? Trying to run the tests locally, it seems like openssl is not happy with it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That loads the ca certificate so it can verify the client cert properly. What error are you getting?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was my bad. dune runtest works but dune exec lib_test/test_client.exe couldn't find the certificates.

I'm exploring how to make both work with dune-sites

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably related to the relative paths

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed the paths and now I'm getting an infinite loop running the client certs test. Similar to what I see in #94 (CI just hangs)

Copy link
Contributor Author

@Firgeis Firgeis Apr 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Retrieving the client certs here also uses relative paths
https://github.com/Firgeis/piaf/blob/fd5e07ceea0ef9d072abc1b39d39229c1300b85f/lib_test/test_client.ml#L225
We should probably add a try block there

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not the issue. The problem is that the server never returns if it can't verify the peer. So the try / catch around the client request is useless because the server never really returns a response.

Copy link
Contributor Author

@Firgeis Firgeis Apr 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strange, because when I run the following test:

(* No client certificate provided *)
(which covers that case when the client doesn't send the client cert and the server verifies it) is passing, at least when running dune test

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My suggestion was a try block around the reading of the certs not the client request, sorry if I was unclear

anmonteiro added a commit that referenced this pull request May 28, 2021
anmonteiro added a commit to anmonteiro/opam-repository that referenced this pull request Sep 6, 2024
CHANGES:

- Improve certificate checking and authentication
  ([anmonteiro/piaf#93](anmonteiro/piaf#93)) -
  [@Firgeis](https://github.com/Firgeis)
- Check certificate SAN IP address when appropriate
  ([anmonteiro/piaf#96](anmonteiro/piaf#96)) -
  [@Firgeis](https://github.com/Firgeis)
- Close the file descriptor when failing to open a connection
  ([anmonteiro/piaf#97](anmonteiro/piaf#97)) -
  [@EduardoRFS](https://github.com/EduardoRFS)
- Yield to other threads when reading a message body. This improves fairness
  for large message bodies
  ([anmonteiro/piaf#100](anmonteiro/piaf#100))
- Add error handling to `Response.of_file`
  ([anmonteiro/piaf#103](anmonteiro/piaf#103))
- Add `Client.send` which sends a `Request.t`
  ([anmonteiro/piaf#110](anmonteiro/piaf#110))
- openssl: set the client verify callback
  ([anmonteiro/piaf#112](anmonteiro/piaf#112))
- Piaf.Response: add `or_internal_error`
  ([anmonteiro/piaf#120](anmonteiro/piaf#120))
- Piaf.Response: Add `Body.sendfile` and `Response.sendfile`
  ([anmonteiro/piaf#124](anmonteiro/piaf#124))
- Piaf.Config: Add `config.flush_headers_immediately`
  ([anmonteiro/piaf#125](anmonteiro/piaf#125))
- Piaf.Server: Add `config.shutdown_timeout` to wait before shutting down the
  Piaf server ([anmonteiro/piaf#174](anmonteiro/piaf#174))
- Websocket support ([anmonteiro/piaf#139](anmonteiro/piaf#139))
- Multicore support ([anmonteiro/piaf#151](anmonteiro/piaf#151))
- Allow binding to UNIX domain socket
  ([anmonteiro/piaf#161](anmonteiro/piaf#161))
- Don't send invalid HTTP/2 headers
  ([anmonteiro/piaf#197](anmonteiro/piaf#197))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants