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

Fix default value for SSL::Context default_verify_param #5601

Merged
merged 1 commit into from
Jan 25, 2018

Conversation

waj
Copy link
Member

@waj waj commented Jan 17, 2018

This is a fix for #5266 but it might require a review from someone with better understanding of x509.

We've just been debugging this issue with @ggiraldez and found that it seems like the verify parameters are inverted for Client and Server.

GitHub certificates has both key usages (client and server) and that's why they pass the verification, but Google new certificate has only "server" usage.

We'd like to actually know if this verification must be enabled by default on every context. Otherwise, just the validity of the certificate is checked.

@jhass what do you think?

@waj waj changed the title Bug: default_verify_param are inverted in SSL::Context::Client and SSL::Context::Server (fixes #5266) Fix default value for SSL::Context default_verify_param Jan 17, 2018
@will
Copy link
Contributor

will commented Jan 18, 2018

Adding this as a monkey patch to my app did work to let me use google oauth without the insecure context workarounds:

abstract class OpenSSL::SSL::Context
  class Client < Context
    def initialize(method : LibSSL::SSLMethod = Context.default_method)
      super(method)

      self.verify_mode = OpenSSL::SSL::VerifyMode::PEER
      {% if LibSSL::OPENSSL_102 %}
        self.default_verify_param = "ssl_server"
        {% end %}
    end
  end

  class Server < Context
    def initialize(method : LibSSL::SSLMethod = Context.default_method)
      super(method)

      add_options(OpenSSL::SSL::Options::CIPHER_SERVER_PREFERENCE)
      {% if LibSSL::OPENSSL_102 %}
        self.default_verify_param = "ssl_client"
        {% end %}

      set_tmp_ecdh_key(curve: LibCrypto::NID_X9_62_prime256v1)
    end
  end
end

@waj waj requested review from jhass, RX14 and ysbaddaden January 18, 2018 02:27
Copy link
Member

@jhass jhass left a comment

Choose a reason for hiding this comment

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

Looks good to me. I'm unable to unearth any useful docs on this right now and I don't remember how I figured this out initially, so probably reading openssl source code -> likely that I just missed this :)

@ysbaddaden
Copy link
Contributor

I suppose it's fine. Any reference anywhere about that?

@waj
Copy link
Member Author

waj commented Jan 18, 2018

@ysbaddaden No, I couldn't find a good reference about this. I didn't test the server part and I wonder what it's actually verifying there? I guess is the client certificate in case there is one. Can client requests still be made without a client certificate?

@ysbaddaden
Copy link
Contributor

Documentation is available in the x509 man page under CERTIFICATE EXTENSIONS:
https://www.openssl.org/docs/manmaster/man1/x509.html

SSL certificates may have a "purpose" to add another level of trust and verification to the certificate. For example a certificate may be trusted as a SSL Client (or SSL Server) and should be refused when it acts for another purposes.

I assume the X509 context verification is meant to verify the received certificate, which means a server will verify a client certificate, and a client will verify a server certificate. I assume we got the purposes wrong? The OpenSSL API makes it confusing, since we set the purpose on the SSL context (client/server) but must set an opposite value (server/client)...

@ysbaddaden
Copy link
Contributor

Maybe we should document this, and properly explain in the commit message (since the value is weird, a git blame will help).

Copy link
Contributor

@RX14 RX14 left a comment

Choose a reason for hiding this comment

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

Can verify this fix.

@RX14
Copy link
Contributor

RX14 commented Jan 24, 2018

I agree that a bit of docs should be added though.

…L::Context::Server

Fixes #5266

x509 certificates have a purpose associated to them. Clients should
verify that the server's certificate is intended to be used in a
server, and servers should check the client's certificate is
intended to be used for clients.

Crystal was mistakingly checking those mixed up.

See https://wiki.openssl.org/index.php?title=Manual:X509(1)&oldid=1797#CERTIFICATE_EXTENSIONS
See https://tools.ietf.org/html/rfc5280#section-4.2.1.3
@matiasgarciaisaia matiasgarciaisaia changed the base branch from master to release/0.24 January 25, 2018 20:01
@matiasgarciaisaia
Copy link
Member

@waj @RX14 @ysbaddaden @jhass I've updated the commit's message to reflect why are we changing this, with the relevant OpenSSL/x509 RFC docs linked.

I've also rebased this to be included in a future 0.24.2 release.

Do you think this is OK? Any ideas on how to clarify further?

@matiasgarciaisaia matiasgarciaisaia added this to the 0.24.2 milestone Jan 25, 2018
Copy link
Contributor

@ysbaddaden ysbaddaden left a comment

Choose a reason for hiding this comment

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

👍

@matiasgarciaisaia matiasgarciaisaia merged commit bb7e1ec into release/0.24 Jan 25, 2018
@RX14
Copy link
Contributor

RX14 commented Jan 25, 2018

Ensure this is cherry-picked into master please.

@RX14
Copy link
Contributor

RX14 commented Feb 2, 2018

This is still not cherry-picked into master. This is why I dislike all these weird release branches.

@asterite asterite deleted the fix/5266-ssl-verify branch April 27, 2018 21:11
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.

7 participants